2011-11-11 28 views
7

Nếu một đối tượng có Single Responsibility, có thể những điều sau đây được chấp nhận:đơn Trách nhiệm và phụ thuộc

public class Person 
{ 
    public string Name; 
    public DateTime DateOfBirth; 

    private IStorageService _storageService; 

    public Person(IStorageService storageService) 
    { 
     _storageService = storageService 
    } 

    public void Save() 
    { 
     _storageService.Persist(this); 
    } 
} 

ví dụ: sử dụng cộng tác viên cung cấp (mà cũng giúp ngăn chặn các mô hình miền là thiếu máu).

Hoặc nó nên là:

public class Person 
{ 
    public string Name; 
    public DateTime DateOfBirth; 

    public Person() 
    { 
    } 


} 
public class StorageService 
{ 
    public void Persist(Person p) 
    { 
    } 
} 
+0

Tôi thường thấy sau. Lợi thế của cái cũ là gì? – phoog

+1

Tôi nghĩ rằng lớp người không có kinh doanh thực sự biết về các storageservice, nó cặp vợ chồng người lớp để một dịch vụ lưu trữ mà làm cho nó ít tái sử dụng – Daniel

Trả lời

10

những điều sau đây có thể chấp nhận được không?

class Person {
Person (IStorageService) {} ...
trống Save() {} ...
}

sự phụ thuộc này không có ý nghĩa.

Trong khi nó không mạnh mẽ vài một Person-Storage, bởi vì nó không ràng buộc chúng vào một cụ thực hiện lưu trữ, tôi cho rằng bất kỳ sự phụ thuộc như vậy làm cho không có ý nghĩa.

Các phương pháp như động từ

Hãy suy nghĩ về phương pháp trên một lớp học như động từ đó sẽ được thực hiện bởi loại đó. Bạn đang nói một trường hợp của loại đó để "làm một cái gì đó", đối với tên miền địa phương của nó.

Điều gì có nghĩa là khi tôi, với tư cách là một người, Save?

  • Tôi đã chuyển nhà cung cấp bảo hiểm và giảm chi phí lên đến 15%?
  • Tôi là một vị thần cứu chuộc?
  • Tôi đã tải xuống linh hồn của mình thành một automaton?

Dịch vụ lưu trữ có thể và nên Save. Mọi người không thể Save và không được quảng cáo rằng họ có thể.

Đang cố gắng để giày sừng nó trong

SaveTo có thể làm cho ý nghĩa hơn - ví dụ: public void SaveTo(IStorageService storage).

Nhưng sau đó bạn đang nói một người có trách nhiệm biết cách lưu chính nó vào bộ nhớ. Theo tôi, đây là a violation of SRP. Nó cũng hiển thị a missing piece of Domain Analysis.

Tên miền cho Person sẽ không chứa bất kỳ nội dung nào về lưu, lưu trữ, v.v. Nó sẽ chứa tương tác giữa mọi người và những thứ khác ở cấp đó của miền. Miền tồn tại của dữ liệu là một nơi tốt hơn cho phương thức Save.

Nếu Person nằm trong miền sự cố (ở mức trừu tượng đó), thì Storage nằm trong miền giải pháp.

Làm thế nào bạn nên tách logic của bạn

Bạn có ba mảnh của logic ở đây:

  1. Person - biết về "người thứ"
  2. Storage - biết về loại đặc biệt dung lượng lưu trữ và cách truy cập vào số điện thoại
  3. Storage of Person - biết về cách một người nên cam kết lưu trữ

Làm theo lời khuyên của tôi ở trên, tôi muốn để lại Person để tự mình thực hiện. Tuy nhiên, bạn có thể tách logic cho StorageStorage of Person hoặc bạn có thể kết hợp chúng.

The approach that ORMs take là phân tách tất cả ba khái niệm. "Ánh xạ" trong "Ánh xạ quan hệ đối tượng" là nơi "Bộ nhớ của người" được đóng gói.

Phương pháp này cho phép logic Storage tập trung vào công việc có khả năng đọc cấu hình bộ nhớ, kết nối với bộ nhớ, đảm bảo lưu trữ nhanh, chọn phương pháp lưu trữ thay thế, v.v. mã lưu trữ có thể được sử dụng lại bởi bất kỳ mô hình tên miền nào khác.

+0

Amen brother !! +1 – Steven

+0

Câu trả lời hoàn hảo, kỹ lưỡng –

+0

Cũng lý luận! Tôi thích nó! –

4

tôi sẽ gắn bó với phiên bản thứ hai. Nếu nó có trách nhiệm duy nhất, bạn có thể sử dụng phiên bản đầu tiên. Nhưng, trong tâm trí của tôi, tôi thích suy nghĩ của một lớp kiên trì tách biệt với các đối tượng mô hình.

Ngoài ra, bạn có thể tuần tự hóa phiên bản thứ 2 có thể hữu ích. Bạn có thể sẽ không thể serialize phiên bản 1 với tham chiếu đến IStorageService.

+0

++ 1 cho Serialization. –

0

Tôi nhận thấy rằng không gian tên miền của bạn đầy đủ và được kiểm tra hơn, chất lượng ứng dụng của bạn càng tốt. Các thực thể bền vững không thuộc về mô hình miền, vì vậy tôi tách riêng hai đối tượng này.

0

Nếu người đó là đối tượng miền mà bạn đang lập mô hình, tôi sẽ không ủng hộ việc nó đóng gói dịch vụ. Ý tôi là, tôi không biết về bạn, nhưng tôi là một người, và tôi không có dịch vụ lưu trữ;)

Tôi muốn nói rằng mối quan ngại về mô hình miền thiếu máu là mối quan tâm về cách thức các đối tượng miền liên quan đến nhau. Đó là thiếu máu nếu họ chỉ đơn giản là túi tài sản của chữ. Bạn có thể không muốn khắc phục điều này bằng cách yêu cầu họ quan tâm đến họ bằng cách mô hình hóa mọi thứ và cũng với việc tìm ra khi nào và làm thế nào để duy trì bản thân.

Xem xét thiếu máu cục bộ sẽ được khắc phục bằng cách có các tương tác phong phú. Có lẽ bạn đang lập mô hình một trường học, và Người là một đối tượng có thể là Học sinh hoặc Giáo viên và Lớp học là một tập hợp các học sinh và một giáo viên. Sau đó bạn sẽ có một số loại khái niệm về myTeacher.Assign (Bài tập về nhà, lớp học) hoặc một cái gì đó tương tự. Đây là cách cá nhân tôi sẽ làm giàu về mô hình miền của tôi - bằng cách mô hình hóa các tương tác thực tế, khái niệm giữa các thực thể miền của bạn, thay vì bằng cách 'mô hình hoá' cách chúng tương tác với mã ống dẫn truy cập dữ liệu của bạn.

Chỉ hai xu của tôi.

4

Nếu bạn đọc kỹ các định nghĩa của SRP, bạn sẽ nhận thấy rằng định nghĩa của một trách nhiệm là một lý do để thay đổi .

Phiên bản đầu tiên có thể có hai lý do để thay đổi:

  • API kiên trì thay đổi
  • Hình dạng của giá trị của nó thay đổi

Vì vậy, nó không tuân theo các SRP, trong khi phiên bản thứ hai.

+2

Câu trả lời tuyệt vời "trong một câu trả lời". –

0

Theo Nguyên tắc về trách nhiệm duy nhất, một lớp học chỉ nên có một lý do để thay đổi. Lý do hoặc nguồn thay đổi là các bộ phận kinh doanh khác nhau mà chúng tôi tạo ra và thiết kế các lớp khác nhau. Vì vậy, để biết nếu có vi phạm SRP, nhà thiết kế cần biết các phòng ban kinh doanh khác nhau mà anh ấy làm việc và thiết kế các lớp học sao cho không có lớp nào có hành vi hoặc tiểu bang cho nhiều bộ phận. Điều này có thể khác nhau từ doanh nghiệp đến doanh nghiệp.

Mặc dù trong ví dụ đầu tiên do bạn cung cấp, rõ ràng có thể có hai nguồn thay đổi, tức là quản lý khách hàng (để quản lý tên khách hàng, ngày sinh) và Quản trị viên cơ sở dữ liệu/Schema Designer (lưu khách hàng vào cơ sở dữ liệu). Vì vậy, rõ ràng là vi phạm SRP.

Trong ví dụ thứ hai, bạn đang quản lý hai nguồn thay đổi khác nhau trong hai lớp khác nhau.Vì vậy, tôi sẽ nói ví dụ thứ hai là chính xác. Mặc dù tôi sẽ đổi tên lớp :).

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