2011-12-06 30 views
5

Ngôn ngữ lập trình của tôi là C#. Tôi đã có một câu hỏi liên quan đến sự thiếu hiểu biết trong mô hình miền của tôi.Dốt không liên tục Miền lớp

Giả sử tôi đã có một lớp người như vậy:

public class Person 
{ 
    private string email; 

    public string Email 
    { 
     get { return email; } 
     set { email = value; } 
    } 

    public Person(string email) 
    { 
     this.email = email; 
    } 
} 

Bây giờ, trong mô hình tên miền của tôi, có một quy tắc rằng không thể có hai người có địa chỉ email. Vì vậy, khi instantiating một người mới, điều này cần phải được xác nhận cũng như khi thay đổi tài sản email. Vì vậy, tôi đã tự hỏi làm thế nào bạn sẽ giải quyết một xác nhận như vậy trong bạn kiên trì lớp miền không biết gì. Những gì tôi hiện đang làm là sử dụng một mô hình nhà máy cho người instantiation trong đó tôi tiêm một kho lưu trữ người. Ở đó tôi có thể tìm kiếm người khác có cùng địa chỉ email. Cũng giống như vậy:

public class PersonFactory 
{ 
    private static readonly IPersonRepository personRepository; 

    public Person CreateNewPerson(string email) 
    { 
     Person personWithSameMail = personRepository.GetPersonByEmail(email); 

     if (personWithSameMail != null) 
      throw new ApplicationException("Email already exists."); 

     return new Person(email); 
    } 

    public PersonFactory(IPersonRepository personRepository) 
    { 
     this.personRepository = personRepository; 
    } 
} 

Nhưng sử dụng giải pháp này, việc kiểm tra khi thay đổi địa chỉ email người (mà có thể là một trường hợp kinh doanh hợp lệ) vẫn chưa được bảo hiểm. Hơn nữa lớp Person vẫn tiếp xúc với một nhà xây dựng công cộng và bằng cách bỏ qua nhà máy, những người có địa chỉ email trùng lặp vẫn có thể thực hiện được.

Bất kỳ giải pháp thanh lịch nào cho điều này?

P.S. Để tất cả các dữ liệu người làm trung tâm: Không, tôi không muốn để xác nhận email dupe trong lớp truy cập dữ liệu;)

UPDATE:

Có lẽ toàn bộ câu hỏi này là lỗi thời anyways. Việc kiểm tra các email trùng lặp theo ngữ cảnh của mô hình miền sẽ luôn yêu cầu "cái gì đó" nhận thức được tất cả mọi người - một gốc. "Cái gì đó" có thể là một sổ địa chỉ, hoặc cả thế giới chứa tất cả những người có địa chỉ email. Vì vậy, có lẽ tôi đang pha trộn các lập trình viên cần các giải pháp kỹ thuật thanh lịch cho các vấn đề, mà tồn tại chỉ vì thiếu một mô hình miền hoàn chỉnh và cũng nghĩ ra. Đây có phải là trường hợp ở đây không? Điều đó không chỉ là một người có địa chỉ email trôi nổi trong không gian (hey, không gian sẽ là gốc tổng hợp của tôi ở đây;)) chỉ vì niềm vui của sự tồn tại? Nhưng nếu đây là một trường hợp kinh doanh thực sự như một ứng dụng sổ địa chỉ, sổ địa chỉ sẽ là tổng hợp của người và do đó có thể kiểm tra tất cả mọi người trong bộ sưu tập nội bộ của nó để đảm bảo rằng không có địa chỉ email trùng lặp.

+0

Tại sao bạn không tạo hàm tạo nội bộ và cũng kiểm tra địa chỉ email khi cập nhật? Và tôi không nghĩ rằng đó là một giải pháp tốt đẹp để cung cấp một kho lưu trữ cho một nhà máy. Chức năng dịch vụ gọi cho nhà máy nên kiểm tra xem địa chỉ email đã tồn tại chưa. –

+0

@WouterdeKort: Tôi không đồng ý với nhận xét của bạn: (1) Làm cho nội bộ ctor không giúp gì cả. Nó vẫn cho phép tạo người dùng với địa chỉ thư trùng lặp. (2) Làm cho phương thức gọi nhà máy làm việc kiểm tra có hiệu quả loại bỏ quy tắc kinh doanh đó. Nó bây giờ là đến người gọi để thực thi quy tắc này. Đó chỉ là thiết kế API rất kém –

+0

@DanielHilgarth Ông đề cập một cách rõ ràng rằng nhà xây dựng công cộng là một vấn đề. Một nhà máy nên xây dựng một đối tượng với tất cả các phụ thuộc và giá trị yêu cầu. Trộn logic kinh doanh với một nhà máy là cái gì tôi sẽ gọi là thiết kế xấu. –

Trả lời

2

Tôi không phải là chuyên gia về DDD nhưng việc tôi thực hiện nó là như thế này.

Trước hết, đối với tôi lỗ hổng lớn nhất trong thiết kế của bạn là cho phép người định cư trên thực thể. Điều đó có nghĩa rằng bạn có thể thay đổi trạng thái của pháp nhân của bạn mà không có gốc tổng thể biết về nó. Tôi sẽ refactor nó loại bỏ các setters và và cho phép chỉ cần thiết lập nó thông qua các nhà xây dựng tại tạo đối tượng.

Một điểm khác. Thực thể cá nhân không nên thực hiện xác thực email (dưới dạng kiểm tra xem email đã được sử dụng hay chưa), bởi vì nó chỉ có thể nhận thức được trạng thái của chính nó và các thực thể con liên quan nếu cô ta là gốc của tổng hợp. Sau đó, bạn nên có một tham chiếu đến kho lưu trữ từ thực thể đó là cho tôi thiết kế xấu. Đó là lý do tại sao bạn đã sử dụng nhà máy tôi nghĩ.

Tôi cho rằng việc xác thực đầu tiên sẽ xảy ra trong giao diện người dùng để thất bại càng nhanh càng tốt. Nhưng nó không đủ. Khi duy trì trạng thái tên miền của bạn, bạn nên thực thi quy tắc mà Người có một email duy nhất.Tôi nghĩ rằng xác nhận sẽ xảy ra trong dịch vụ miền ví dụ gọi PersonRegistrationService mà có thể có một tham chiếu đến IPersonRepository và trước khi thêm các thực thể người vào bộ sưu tập của mình để tồn tại, nó sẽ kiểm tra đầu tiên nếu các email cá nhân là độc nhất. Nếu không, tôi sẽ thông báo cho người dùng lỗi và không thêm thực thể.

Bạn nghĩ sao?

+0

Như tôi đã hiểu từ những gì bạn đề xuất, việc tạo một người nên là miền nội bộ. Và sau đó, sẽ có một dịch vụ đăng ký có hành vi giống như một thứ xác nhận trợ cấp của một người thậm chí còn tồn tại với tên miền, đúng không? Vì vậy, dịch vụ này sẽ nhận được tất cả các thuộc tính bắt buộc của người đầu tiên làm đối số và sau đó, bằng cách tiêm kho, có thể chăm sóc "là người có dữ liệu đã cho phép tồn tại"? – Chris

+0

Tôi nghĩ rằng dịch vụ này là nơi đầu tiên một loại khái niệm miền. Tôi đã đề xuất Dịch vụ đăng ký vì việc tạo Người từ không khí mỏng không có ý nghĩa với tôi. Vì vậy, trách nhiệm của dịch vụ đó sẽ là lấy các đối số (hoặc thậm chí là thực thể Person mới mà tại thời điểm này không thuộc về trạng thái của miền), xác minh với kho lưu trữ nếu email là duy nhất và sau đó thêm người vào đó bộ sưu tập nội bộ (sẽ được ORM lưu giữ hoặc khác, nhưng nó không chỉ quan trọng ở đây). –

+0

Có thể những người khác lại phải thực hiện việc này nhưng có vẻ như hợp lý để chuyển qua dịch vụ miền. Trong thực tế nó khá giống với nhà máy của bạn nhưng sự khác biệt là dịch vụ có ý nghĩa tên miền và thêm người sau khi xác thực thành công vào kho lưu trữ (là một tập hợp các thực thể Person được duy trì) –

Các vấn đề liên quan