Liệu thiết kế lớp học này có vi phạm nguyên tắc trách nhiệm duy nhất?


63

Hôm nay tôi đã cãi nhau với ai đó.

Tôi đã giải thích những lợi ích của việc có một mô hình miền phong phú trái ngược với mô hình miền thiếu máu. Và tôi đã giới thiệu quan điểm của mình với một lớp đơn giản như thế:

public class Employee
{
    public Employee(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastname;
    }

    public string FirstName { get private set; }
    public string LastName { get; private set;}
    public int CountPaidDaysOffGranted { get; private set;}

    public void AddPaidDaysOffGranted(int numberOfdays)
    {
        // Do stuff
    }
}

Khi anh bảo vệ cách tiếp cận mô hình thiếu máu của mình, một trong những lập luận của anh là: "Tôi là người tin tưởng vào RẮN . Bạn đang vi phạm nguyên tắc trách nhiệm duy nhất (SRP) vì bạn vừa thể hiện dữ liệu và thực hiện logic trong cùng một lớp."

Tôi thấy tuyên bố này thực sự đáng ngạc nhiên, vì theo lý do này, bất kỳ lớp nào có một thuộc tính và một phương thức đều vi phạm SRP, và do đó, OOP nói chung không phải là RẮN, và lập trình chức năng là cách duy nhất để lên thiên đàng.

Tôi quyết định không trả lời nhiều tranh luận của anh ấy, nhưng tôi tò mò không biết cộng đồng nghĩ gì về câu hỏi này.

Nếu tôi đã trả lời, tôi sẽ bắt đầu bằng cách chỉ ra nghịch lý được đề cập ở trên, và sau đó chỉ ra rằng SRP phụ thuộc nhiều vào mức độ chi tiết mà bạn muốn xem xét và nếu bạn đưa nó đủ xa, thì bất kỳ lớp nào có nhiều hơn một tài sản hoặc một phương pháp vi phạm nó.

Bạn sẽ nói gì?

Cập nhật: Ví dụ đã được guntbert cập nhật rộng rãi để làm cho phương thức thực tế hơn và giúp chúng tôi tập trung vào các cuộc thảo luận cơ bản.


19
lớp này vi phạm SRP không phải vì nó trộn dữ liệu với logic, mà vì nó có độ gắn kết thấp - đối tượng Chúa
gnat

1
Mục đích gì là thêm ngày lễ cho nhân viên? Có lẽ nên có một lớp lịch hoặc một cái gì đó có ngày lễ. Tôi nghĩ bạn của bạn là đúng.
James Black

9
Đừng bao giờ nghe ai đó nói rằng "Tôi là người tin vào X".
Stig Hemmer

29
Không có quá nhiều cho dù điều này có vi phạm SRP hay không, liệu nó có phải là mô hình tốt hay không. Giả sử tôi là một nhân viên. Khi tôi hỏi người quản lý của mình rằng anh ấy có ổn không nếu tôi đi trượt tuyết vào cuối tuần dài, người quản lý của tôi không thêm ngày nghỉ cho tôi . Mã ở đây không phù hợp với thực tế mà nó dự định mô hình, và do đó là đáng ngờ.
Eric Lippert

2
+1 cho lập trình chức năng là cách duy nhất lên thiên đàng.
xóa

Câu trả lời:


68

Trách nhiệm duy nhất nên được hiểu là sự trừu tượng hóa các nhiệm vụ logic trong hệ thống của bạn. Một lớp nên có trách nhiệm duy nhất (làm mọi thứ cần thiết để) thực hiện một nhiệm vụ cụ thể, duy nhất. Điều này thực sự có thể mang lại rất nhiều vào một lớp được thiết kế tốt, tùy thuộc vào trách nhiệm là gì. Lớp chạy công cụ tập lệnh của bạn, ví dụ, có thể có rất nhiều phương thức và dữ liệu liên quan đến việc xử lý tập lệnh.

Đồng nghiệp của bạn đang tập trung vào những điều sai trái. Câu hỏi không phải là "lớp học này có gì?" nhưng "lớp hoạt động hữu ích nào mà lớp này thực hiện trong chương trình?" Một khi điều đó được hiểu, mô hình miền của bạn trông ổn.


Nếu Lập trình hướng đối tượng được tạo và dự định mô hình hóa các đối tượng và lớp thực tế (hành động + thuộc tính) thì tại sao không viết lớp mã có nhiều trách nhiệm (hành động)? Một đối tượng trong thế giới thực có thể có nhiều trách nhiệm. Ví dụ, một nhà báo viết bài xã luận trên các tờ báo và phỏng vấn các chính trị gia trong một chương trình truyền hình. Hai trách nhiệm cho một đối tượng thực tế cuộc sống! Nếu tôi sẽ viết một lớp Nhà báo thì sao?
user1451111

41

Nguyên tắc trách nhiệm duy nhất chỉ liên quan đến việc có hay không một đoạn mã (trong OOP, thông thường chúng ta đang nói về các lớp) có trách nhiệm đối với một phần chức năng . Tôi nghĩ rằng bạn của bạn nói rằng các chức năng và dữ liệu không thể kết hợp không thực sự hiểu ý tưởng đó. Nếu Employeecũng có chứa thông tin về nơi làm việc của anh ta, xe của anh ta đi nhanh như thế nào và loại thức ăn mà con chó của anh ta ăn thì chúng ta sẽ gặp vấn đề.

Vì lớp này chỉ liên quan đến một Employee, tôi nghĩ thật công bằng khi nói nó không vi phạm SRP một cách trắng trợn, nhưng mọi người luôn có ý kiến ​​riêng của họ.

Một nơi mà chúng tôi có thể cải thiện là tách thông tin Nhân viên (như tên, số điện thoại, email) khỏi kỳ nghỉ của anh ấy. Trong tâm trí của tôi, điều này không có nghĩa là các phương thức và dữ liệu không thể kết hợp với nhau , nó chỉ có nghĩa là có lẽ chức năng nghỉ có thể ở một nơi riêng biệt.


20

Theo tôi, lớp này có khả năng vi phạm SRP nếu nó tiếp tục đại diện cho cả EmployeeEmployeeHolidays.

Vì nó là như vậy, và nếu nó đến với tôi để xem xét ngang hàng, có lẽ tôi sẽ để nó qua. Nếu nhiều thuộc tính và phương thức cụ thể của Nhân viên được thêm vào, và các thuộc tính cụ thể cho kỳ nghỉ được thêm vào, tôi có thể khuyên bạn nên chia tách, trích dẫn cả SRP và ISP.


Tôi đồng ý. Nếu mã đơn giản như được cung cấp ở đây, tôi có thể sẽ để nó trượt. Nhưng trong tâm trí của tôi, tôi không nên có trách nhiệm của Nhân viên để xử lý kỳ nghỉ của riêng mình. Nó có vẻ không phải là một vấn đề lớn với trách nhiệm được đặt ở đâu, nhưng hãy nhìn nó theo cách này: Nếu bạn chưa quen với cơ sở mã và phải làm việc với chức năng dành riêng cho kỳ nghỉ - bạn sẽ tìm kiếm ở đâu trước? Đối với logic kỳ nghỉ, cá nhân tôi sẽ KHÔNG nhìn vào thực thể Nhân viên để bắt đầu.
Niklas H

1
@NiklasH Đồng ý. Cá nhân tôi sẽ không nhìn ngẫu nhiên và thử và đoán lớp tôi sẽ tìm kiếm với studio cho từ "Holiday" và xem nó xuất hiện ở lớp nào. :)
NikolaiDante

4
Thật. Nhưng điều gì sẽ xảy ra nếu nó không được gọi là "Kỳ nghỉ" trong hệ thống mới này, mà là "Kỳ nghỉ" hoặc "Thời gian rảnh". Nhưng tôi đồng ý, với điều đó bạn thường có khả năng chỉ tìm kiếm nó hoặc có thể hỏi đồng nghiệp. Nhận xét của tôi chủ yếu là để OP mô hình hóa tinh thần trách nhiệm và nơi rõ ràng nhất cho logic sẽ là :-)
Niklas H

Tôi đồng ý với tuyên bố đầu tiên của bạn. Tuy nhiên, nếu được đánh giá ngang hàng, tôi không nghĩ mình sẽ làm thế vì vi phạm SRP là một con dốc trơn trượt và đây có thể là cửa sổ đầu tiên trong số nhiều cửa sổ bị vỡ. Chúc mừng.
Loa Jim

20

Đã có những câu trả lời tuyệt vời chỉ ra rằng SRP là một khái niệm trừu tượng về chức năng logic, nhưng có những điểm tinh tế hơn mà tôi nghĩ là đáng để thêm vào.

Hai chữ cái đầu tiên trong RẮN, SRP và OCP, đều nói về cách mã của bạn thay đổi để đáp ứng với thay đổi trong yêu cầu. Định nghĩa yêu thích của tôi về SRP là: "một mô-đun / lớp / chức năng chỉ nên có một lý do để thay đổi." Tranh luận về các lý do có khả năng khiến mã của bạn thay đổi sẽ hiệu quả hơn nhiều so với tranh luận về việc liệu mã của bạn có RẮN hay không.

Có bao nhiêu lý do để lớp nhân viên của bạn phải thay đổi? Tôi không biết, vì tôi không biết bối cảnh bạn đang sử dụng nó và tôi cũng không thể nhìn thấy tương lai. Những gì tôi có thể làm là động não thay đổi có thể dựa trên những gì tôi đã thấy trong quá khứ và bạn có thể đánh giá một cách chủ quan khả năng của chúng. Nếu có nhiều hơn một điểm giữa "khả năng hợp lý" và "mã của tôi đã thay đổi vì lý do chính xác đó", thì bạn đang vi phạm SRP chống lại loại thay đổi đó. Đây là một: ai đó có nhiều hơn hai tên tham gia công ty của bạn (hoặc một kiến ​​trúc sư đọc bài viết W3C tuyệt vời này ). Đây là một điều khác: công ty của bạn thay đổi cách phân bổ ngày nghỉ.

Lưu ý rằng những lý do này có giá trị như nhau ngay cả khi bạn xóa phương thức AddHoliday. Rất nhiều mô hình miền thiếu máu vi phạm SRP. Nhiều trong số chúng chỉ là bảng mã cơ sở dữ liệu và rất phổ biến khi các bảng cơ sở dữ liệu có hơn 20 lý do để thay đổi.

Đây là một cái gì đó để nhai: lớp nhân viên của bạn sẽ thay đổi nếu hệ thống của bạn cần theo dõi lương nhân viên? Địa chỉ? Thông tin liên lạc khẩn cấp? Nếu bạn nói "có" (và "có khả năng xảy ra") với hai trong số đó, thì lớp của bạn sẽ vi phạm SRP ngay cả khi chưa có mã trong đó! RẮN là về các quy trình và kiến ​​trúc cũng như về mã.


9

Lớp đại diện cho dữ liệu không phải là trách nhiệm của lớp, nó là một chi tiết thực hiện riêng tư.

Lớp có một trách nhiệm, đại diện cho một nhân viên. Trong ngữ cảnh này, điều đó có nghĩa là nó trình bày một số API công khai cung cấp cho bạn chức năng bạn cần để đối phó với nhân viên (liệu AddHoliday có phải là một ví dụ hay không gây tranh cãi).

Việc thực hiện là nội bộ; nó xảy ra rằng điều này cần một số biến riêng tư và một số logic. Điều đó không có nghĩa là lớp bây giờ có nhiều trách nhiệm.


Dòng suy nghĩ thú vị, cảm ơn rất nhiều vì đã chia sẻ
tobiak777

Nice - Cách tốt để thể hiện các mục tiêu dự định của OOP.
dùng949300

5

Ý tưởng rằng trộn lẫn logic và dữ liệu theo bất kỳ cách nào luôn luôn sai, thật nực cười, nó thậm chí không đáng để thảo luận. Tuy nhiên, thực sự có một sự vi phạm rõ ràng về trách nhiệm đơn lẻ trong ví dụ, nhưng không phải vì có tài sản DaysOfHolidaysvà chức năng AddHolidays(int).

Đó là bởi vì danh tính của nhân viên được xen kẽ với quản lý kỳ nghỉ, điều này thật tệ. Danh tính của nhân viên là một điều phức tạp cần có để theo dõi kỳ nghỉ, tiền lương, làm thêm giờ, để đại diện cho ai thuộc nhóm nào, để liên kết với báo cáo hiệu suất, v.v. Một nhân viên cũng có thể thay đổi tên, họ hoặc cả hai và giữ nguyên Nhân viên. Nhân viên thậm chí có thể có nhiều cách viết tên của họ như ASCII và chính tả unicode. Mọi người có thể có 0 đến n tên và / hoặc họ. Họ có thể có tên khác nhau trong khu vực pháp lý khác nhau. Theo dõi danh tính của một nhân viên là đủ trách nhiệm mà quản lý kỳ nghỉ hoặc kỳ nghỉ có thể được thêm lên hàng đầu mà không gọi đó là trách nhiệm thứ hai.


"Theo dõi danh tính của một nhân viên là đủ trách nhiệm mà quản lý kỳ nghỉ hoặc kỳ nghỉ có thể được thêm lên hàng đầu mà không gọi đó là trách nhiệm thứ hai." + Nhân viên có thể có một vài tên, v.v ... Quan điểm của một người mẫu là tập trung vào các sự kiện có liên quan của thế giới thực cho vấn đề trong tay. Có tồn tại các yêu cầu mà mô hình này là tối ưu. Trong các yêu cầu này, Nhân viên chỉ thú vị ở mức độ chúng tôi có thể sửa đổi ngày nghỉ của họ và chúng tôi không quan tâm quá nhiều đến việc quản lý các khía cạnh khác của chi tiết cụ thể trong cuộc sống thực của họ.
tobiak777

@reddy "Nhân viên chỉ thú vị ở mức độ chúng tôi có thể sửa đổi ngày nghỉ của họ" - Điều đó có nghĩa là bạn cần xác định chính xác họ. Ngay khi bạn có một nhân viên, họ có thể thay đổi họ của họ bất cứ lúc nào do kết hôn hoặc ly hôn. Họ cũng có thể thay đổi tên và giới tính của họ. Bạn sẽ sa thải nhân viên nếu họ của họ thay đổi sao cho tên của họ trùng với tên của nhân viên khác? Bạn sẽ không thêm tất cả các chức năng này ngay bây giờ. Thay vào đó bạn sẽ thêm nó khi bạn cần, điều đó là tốt. Bất kể bao nhiêu được thực hiện, trách nhiệm của nhận dạng vẫn như nhau.
Peter

3

"Tôi là người tin tưởng vào RẮN. Bạn đang vi phạm nguyên tắc trách nhiệm duy nhất (SRP) vì bạn vừa thể hiện dữ liệu vừa thực hiện logic trong cùng một lớp."

Giống như những người khác, tôi không đồng ý với điều này.

Tôi sẽ nói rằng SRP bị vi phạm nếu bạn đang thực hiện nhiều hơn một đoạn logic trong lớp. Có bao nhiêu dữ liệu cần được lưu trữ trong lớp để đạt được phần logic duy nhất đó là không liên quan.


Không! SRP không bị vi phạm bởi nhiều phần logic, nhiều phần dữ liệu hoặc bất kỳ sự kết hợp nào của cả hai. Yêu cầu duy nhất là đối tượng nên bám sát mục đích của nó. Mục đích của nó có khả năng có thể đòi hỏi nhiều hoạt động.
Martin Maat

@MartinMaat: Nhiều hoạt động, vâng. Kết quả là một mảnh logic. Tôi nghĩ rằng chúng tôi đang nói điều tương tự nhưng với các điều khoản khác nhau (và tôi rất vui khi cho rằng bạn là người đúng vì tôi không nghiên cứu công cụ này thường xuyên)
Cuộc đua nhẹ nhàng với Monica

2

Tôi không thấy hữu ích trong những ngày này để tranh luận về những gì không và không cấu thành một trách nhiệm duy nhất hoặc một lý do duy nhất để thay đổi. Tôi sẽ đề xuất một Nguyên tắc đau buồn tối thiểu ở vị trí của nó:

Nguyên tắc đau buồn tối thiểu: mã nên tìm cách giảm thiểu xác suất yêu cầu thay đổi hoặc tối đa hóa sự dễ dàng thay đổi.

Thế nào Không nên lấy một nhà khoa học tên lửa để tìm hiểu lý do tại sao điều này có thể giúp giảm chi phí bảo trì và hy vọng nó không phải là một cuộc tranh luận bất tận, nhưng nói chung với RẮN, không phải là thứ gì đó để áp dụng một cách mù quáng ở mọi nơi. Đó là một cái gì đó để xem xét trong khi cân bằng sự đánh đổi.

Đối với xác suất yêu cầu thay đổi, điều đó đi xuống với:

  1. Kiểm tra tốt (độ tin cậy được cải thiện).
  2. Chỉ liên quan đến mã tối thiểu trần cần thiết để làm một cái gì đó cụ thể (điều này có thể bao gồm giảm các khớp nối hướng tâm).
  3. Chỉ cần tạo mã badass theo những gì nó làm (xem Nguyên tắc tạo Badass).

Đối với những khó khăn trong việc thực hiện các thay đổi, nó đi lên với các khớp nối hiệu quả. Thử nghiệm giới thiệu khớp nối hiệu quả nhưng nó cải thiện độ tin cậy. Hoàn thành tốt, nó thường làm tốt hơn hại và hoàn toàn được chấp nhận và thúc đẩy bởi Nguyên tắc đau buồn tối thiểu.

Thực hiện nguyên tắc Badass: các lớp được sử dụng ở nhiều nơi sẽ rất tuyệt vời. Họ nên đáng tin cậy, hiệu quả nếu điều đó liên quan đến chất lượng của họ, vv

Và Nguyên tắc Make Badass gắn liền với Nguyên tắc đau buồn tối thiểu, vì những thứ xấu sẽ tìm thấy xác suất yêu cầu thay đổi thấp hơn so với những thứ hút vào những gì chúng làm.

Tôi đã bắt đầu bằng cách chỉ ra nghịch lý được đề cập ở trên, và sau đó chỉ ra rằng SRP phụ thuộc nhiều vào mức độ chi tiết mà bạn muốn xem xét và nếu bạn đưa nó đủ xa, bất kỳ lớp nào có nhiều hơn một thuộc tính hoặc một phương thức đều vi phạm nó

Từ quan điểm SRP, một lớp hầu như không làm gì chắc chắn sẽ chỉ có một lý do (đôi khi bằng không) để thay đổi:

class Float
{
public:
    explicit Float(float val);
    float get() const;
    void set(float new_val);
};

Điều đó thực tế không có lý do để thay đổi! Nó tốt hơn SRP. Đó là ZRP!

Ngoại trừ tôi sẽ đề nghị nó vi phạm trắng trợn Nguyên tắc Make Badass. Nó cũng hoàn toàn vô giá trị. Một cái gì đó rất ít có thể hy vọng là badass. Nó có quá ít thông tin (TLI). Và tự nhiên khi bạn có một thứ gì đó là TLI, nó không thể làm bất cứ điều gì thực sự có ý nghĩa, ngay cả với thông tin được gói gọn, vì vậy nó phải rò rỉ ra thế giới bên ngoài với hy vọng rằng ai đó sẽ thực sự làm điều gì đó có ý nghĩa và xấu xa. Và sự rò rỉ đó là ổn đối với một cái gì đó chỉ nhằm mục đích tổng hợp dữ liệu và không có gì hơn, nhưng ngưỡng đó là sự khác biệt như tôi thấy giữa "dữ liệu" và "đối tượng".

Tất nhiên một cái gì đó là TMI là xấu là tốt. Chúng tôi có thể đặt toàn bộ phần mềm của chúng tôi trong một lớp. Nó thậm chí có thể chỉ có một runphương pháp. Và ai đó thậm chí có thể lập luận rằng bây giờ nó có một lý do rất rộng để thay đổi: "Lớp này sẽ chỉ cần thay đổi nếu phần mềm cần cải tiến." Tôi thật ngớ ngẩn, nhưng tất nhiên chúng ta có thể tưởng tượng tất cả các vấn đề bảo trì với điều đó.

Vì vậy, có một hành động cân bằng như độ chi tiết hoặc độ thô của các đối tượng bạn thiết kế. Tôi thường đánh giá nó bằng bao nhiêu thông tin bạn phải rò rỉ ra thế giới bên ngoài và bao nhiêu chức năng có ý nghĩa mà nó có thể thực hiện. Tôi thường thấy Nguyên tắc Make Badass hữu ích ở đó để tìm sự cân bằng trong khi kết hợp nó với Nguyên tắc đau buồn tối thiểu.


1

Ngược lại, đối với tôi, mô hình miền thiếu máu phá vỡ một số khái niệm chính OOP (liên kết các thuộc tính và hành vi), nhưng có thể không thể tránh khỏi dựa trên các lựa chọn kiến ​​trúc. Các miền thiếu máu dễ suy nghĩ hơn, ít hữu cơ hơn và tuần tự hơn.

Nhiều hệ thống có xu hướng làm điều này khi nhiều lớp phải chơi với cùng một dữ liệu (lớp dịch vụ, lớp web, lớp máy khách, tác nhân ...).

Việc định nghĩa cấu trúc dữ liệu ở một nơi và hành vi trong các lớp dịch vụ khác sẽ dễ dàng hơn. Nếu cùng một lớp được sử dụng trên nhiều lớp, lớp này có thể phát triển lớn và nó đặt câu hỏi về lớp nào chịu trách nhiệm xác định hành vi mà nó cần và ai có thể gọi các phương thức.

Ví dụ, nó có thể không phải là một ý tưởng tốt hơn một quy trình Đại lý tính toán số liệu thống kê về tất cả nhân viên của bạn có thể gọi một máy tính cho những ngày được trả tiền. Và GUI danh sách nhân viên chắc chắn không cần đến tất cả các tính toán id tổng hợp mới được sử dụng trong tác nhân thống kê này (và dữ liệu kỹ thuật đi kèm với nó). Khi bạn tách riêng các phương thức theo cách này, bạn thường kết thúc bằng một lớp chỉ có cấu trúc dữ liệu.

Bạn có thể dễ dàng tuần tự hóa / giải tuần tự hóa dữ liệu "đối tượng" hoặc chỉ một số trong số chúng hoặc sang định dạng khác (json) ... mà không phải lo lắng về bất kỳ khái niệm / trách nhiệm đối tượng nào. Nó chỉ là dữ liệu đi qua mặc dù. Bạn luôn có thể thực hiện ánh xạ dữ liệu giữa hai lớp (Nhân viên, Nhân viên, Nhân viên,) nhưng Nhân viên thực sự có ý nghĩa gì ở đây?

Vì vậy, có nó phân tách hoàn toàn dữ liệu trong các lớp miền và xử lý dữ liệu trong các lớp dịch vụ nhưng nó ở đây là cần thiết. Hệ thống này đồng thời là một chức năng mang lại giá trị kinh doanh và một kỹ thuật cũng để truyền dữ liệu ở mọi nơi cần thiết trong khi vẫn giữ một phạm vi trách nhiệm đúng (và đối tượng phân tán cũng không giải quyết được điều này).

Nếu bạn không cần tách phạm vi hành vi, bạn có thể tự do đưa các phương thức vào các lớp dịch vụ hoặc trong các lớp miền, tùy thuộc vào cách bạn nhìn thấy đối tượng của mình. Tôi có xu hướng xem một đối tượng là khái niệm "thực", điều này tự nhiên giúp giữ SRP. Vì vậy, trong ví dụ của bạn, nó thực tế hơn so với Boss của nhân viên thêm ngày trả lương được cấp cho PayDayAccount của anh ta. Một nhân viên được thuê bởi công ty, Works, có thể bị ốm hoặc được hỏi lời khuyên và anh ta có tài khoản Payday (ông chủ có thể lấy nó trực tiếp từ anh ta hoặc từ sổ đăng ký PayDayAccount ...) Nhưng bạn có thể tạo một lối tắt tổng hợp ở đây để đơn giản nếu bạn không muốn quá nhiều phức tạp cho một phần mềm đơn giản.


Cảm ơn cho Vince đầu vào của bạn. Vấn đề là, bạn không cần một lớp dịch vụ khi bạn có một miền phong phú. Chỉ có một lớp chịu trách nhiệm cho hành vi đó và đó là thực thể miền của bạn. Các lớp khác (lớp web, UI, v.v.) thường xử lý các DTO và ViewModels và điều này là tốt. Mô hình miền là mô hình hóa tên miền, không thực hiện các công việc UI hoặc gửi tin nhắn qua internet. Thông điệp của bạn phản ánh quan niệm sai lầm phổ biến này, xuất phát từ thực tế là mọi người chỉ đơn giản là không biết làm thế nào để phù hợp với OOP vào thiết kế của họ. Và tôi nghĩ điều này rất buồn - đối với họ.
tobiak777

Tôi không nghĩ rằng tôi có một quan niệm sai lầm về miền giàu OOP, tôi đã thiết kế rất nhiều phần mềm theo cách đó và đúng là nó thực sự tốt cho việc bảo trì / tiến hóa. Nhưng tôi rất tiếc phải nói với bạn đây không phải là viên đạn bạc.
Vince

Tôi không nói là vậy. Để viết một trình biên dịch có lẽ không phải, nhưng đối với hầu hết các dòng ứng dụng kinh doanh / SaaS, tôi nghĩ rằng nó ít nghệ thuật / khoa học hơn nhiều so với những gì bạn đề xuất. Nhu cầu về mô hình miền có thể được chứng minh bằng toán học, các ví dụ của bạn khiến tôi nghĩ đến các thiết kế gây tranh cãi thay vì những hạn chế trong OOP
tobiak777

0

Bạn đang vi phạm nguyên tắc trách nhiệm duy nhất (SRP) vì bạn vừa thể hiện dữ liệu vừa thực hiện logic trong cùng một lớp.

Nghe có vẻ rất hợp lý đối với tôi. Mô hình có thể không có thuộc tính công cộng nếu phơi bày hành động. Về cơ bản, nó là một ý tưởng phân tách truy vấn lệnh. Xin lưu ý rằng Command sẽ có trạng thái riêng cho chắc chắn.


0

Bạn không thể vi phạm Nguyên tắc Trách nhiệm Đơn lẻ vì đó chỉ là một tiêu chí thẩm mỹ, không phải là quy tắc tự nhiên. Đừng bị đánh lừa bởi tên nghe có vẻ khoa học và các chữ cái viết hoa.


1
Đây không phải là một câu trả lời thực sự, nhưng nó sẽ là tuyệt vời như là một nhận xét cho câu hỏi.
Jay Elston
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.