Nguyên tắc trách nhiệm duy nhất - Làm thế nào tôi có thể tránh phân mảnh mã?


57

Tôi đang làm việc trong một nhóm trong đó trưởng nhóm là người ủng hộ mạnh mẽ các nguyên tắc phát triển RẮN. Tuy nhiên, anh ta thiếu rất nhiều kinh nghiệm trong việc đưa phần mềm phức tạp ra khỏi cửa.

Chúng tôi có một tình huống mà anh ấy đã áp dụng SRP cho một cơ sở mã khá phức tạp, hiện đã trở nên rất phân mảnh và khó hiểu và gỡ lỗi.

Bây giờ chúng ta có một vấn đề không chỉ với sự phân mảnh mã, mà còn là sự đóng gói, vì các phương thức trong một lớp có thể là riêng tư hoặc được bảo vệ đã được đánh giá là đại diện cho 'lý do để thay đổi' và đã được trích xuất ra các lớp và giao diện nội bộ hoặc công khai không phù hợp với các mục tiêu đóng gói của ứng dụng.

Chúng tôi có một số nhà xây dựng lớp có hơn 20 tham số giao diện, vì vậy đăng ký và độ phân giải IoC của chúng tôi đang trở thành một con quái vật theo đúng nghĩa của nó.

Tôi muốn biết liệu có bất kỳ 'tái cấu trúc nào từ phương pháp SRP' mà chúng ta có thể sử dụng để giúp khắc phục một số vấn đề này không. Tôi đã đọc được rằng nó không vi phạm RẮN nếu tôi tạo ra một số lớp hạt thô, 'bao bọc' một số lớp có liên quan chặt chẽ để cung cấp một điểm truy cập duy nhất cho tổng số chức năng của chúng (tức là bắt chước ít hơn thực hiện lớp SRP'd quá mức).

Ngoài ra, tôi không thể nghĩ ra một giải pháp nào cho phép chúng tôi tiếp tục thực tế với những nỗ lực phát triển của mình, trong khi vẫn giữ cho mọi người hạnh phúc.

Bất kỳ đề xuất ?


18
Đó chỉ là ý kiến ​​của tôi, nhưng tôi nghĩ còn một quy tắc nữa, rất dễ bị lãng quên dưới đống từ viết tắt khác nhau - "Nguyên tắc ý thức chung". Khi một "giải pháp" tạo ra nhiều vấn đề mà nó thực sự giải quyết, thì có gì đó không ổn. Tôi nghĩ rằng nếu một vấn đề phức tạp, nhưng được bao bọc trong một lớp học quan tâm đến những rắc rối của nó và vẫn còn tương đối dễ gỡ lỗi - tôi sẽ để nó một mình. Nói chung, ý tưởng 'trình bao bọc' của bạn có vẻ hợp với tôi, nhưng tôi sẽ để lại câu trả lời cho người hiểu biết hơn.
Patryk Ćwiek

6
Đối với "lý do để thay đổi" - không cần phải suy đoán về tất cả các lý do sớm. Đợi cho đến khi bạn thực sự phải thay đổi điều đó, và sau đó xem những gì có thể được thực hiện để làm cho loại thay đổi đó dễ dàng hơn trong tương lai.

62
Một lớp với 20 tham số hàm tạo không nghe rất SRP đối với tôi!
MattDavey

1
Bạn viết "... Đăng ký và giải quyết IoC ..."; điều này nghe có vẻ như bạn (hoặc nhóm trưởng của bạn) nghĩ rằng "IoC" và "tiêm phụ thuộc" (DI) là điều tương tự, điều đó không đúng. DI là một phương tiện để đạt được IoC, nhưng chắc chắn không phải là duy nhất. Bạn nên phân tích cẩn thận lý do tại sao bạn muốn làm IoC; nếu đó là vì bạn muốn viết các bài kiểm tra đơn vị, thì bạn cũng có thể thử sử dụng mẫu định vị dịch vụ hoặc đơn giản là các lớp giao diện ( ISomething). IMHO, các phê duyệt này dễ xử lý hơn nhiều so với tiêm phụ thuộc và dẫn đến mã dễ đọc hơn.

2
bất kỳ câu trả lời nào được đưa ra ở đây sẽ ở trong chân không; chúng ta phải xem mã để đưa ra phản hồi cụ thể. 20 tham số trong một constructor? tốt, bạn có thể đang thiếu một đối tượng ... hoặc tất cả chúng có thể hợp lệ; hoặc chúng có thể thuộc về một tệp cấu hình, hoặc chúng có thể thuộc về một lớp DI hoặc ... Các triệu chứng chắc chắn nghe có vẻ đáng ngờ, nhưng giống như hầu hết mọi thứ trong CS, "nó phụ thuộc" ...
Steven A. Lowe

Câu trả lời:


85

Nếu lớp của bạn có 20 tham số trong hàm tạo, có vẻ như nhóm của bạn không biết SRP là gì. Nếu bạn có một lớp chỉ làm một việc, làm thế nào để nó có 20 phụ thuộc? Điều đó giống như đi câu cá và mang theo cần câu cá, hộp câu, vật dụng chăn, bóng bowling, côn nhị khúc, người ném lửa, v.v .... Nếu bạn cần tất cả những thứ đó để đi câu, bạn không chỉ đi câu.

Điều đó nói rằng, SRP, giống như hầu hết các nguyên tắc ngoài kia, có thể được áp dụng quá mức. Nếu bạn tạo một lớp mới để tăng số nguyên, thì ừ, đó có thể là một trách nhiệm duy nhất, nhưng thôi nào. Điều đó thật nực cười. Chúng ta có xu hướng quên rằng những thứ như các nguyên tắc RẮN là có mục đích. RẮN là một phương tiện để kết thúc, không phải là kết thúc trong chính nó. Sự kết thúc là khả năng duy trì . Nếu bạn sắp có được chi tiết đó với Nguyên tắc Trách nhiệm duy nhất, thì đó là một chỉ số nhiệt tình cho RẮN đã làm cho nhóm mù quáng với mục tiêu RẮN.

Vì vậy, tôi đoán những gì tôi đang nói là ... SRP không phải là vấn đề của bạn. Đó là một sự hiểu lầm về SRP, hoặc một ứng dụng cực kỳ chi tiết của nó. Hãy cố gắng để nhóm của bạn giữ điều chính là điều chính. Và điều chính là khả năng bảo trì.

BIÊN TẬP

Khiến mọi người thiết kế các mô-đun theo cách khuyến khích sự dễ sử dụng. Hãy nghĩ về mỗi lớp như một API nhỏ. Trước tiên hãy nghĩ, "Làm thế nào tôi muốn sử dụng lớp này", và sau đó thực hiện nó. Đừng chỉ nghĩ rằng "Lớp học này cần phải làm gì." SRP thực sự có xu hướng làm cho các lớp khó sử dụng hơn, nếu bạn không suy nghĩ nhiều về khả năng sử dụng.

CHỈNH SỬA 2

Nếu bạn đang tìm kiếm các mẹo về tái cấu trúc, bạn có thể bắt đầu thực hiện những gì bạn đã đề xuất - tạo các lớp chi tiết thô hơn để bọc một số lớp khác. Hãy chắc chắn rằng lớp hạt thô vẫn tuân thủ SRP , nhưng ở mức cao hơn. Sau đó, bạn có hai lựa chọn thay thế:

  1. Nếu các lớp hạt mịn hơn không còn được sử dụng ở nơi nào khác trong hệ thống, bạn có thể dần dần kéo việc triển khai chúng vào lớp hạt thô và xóa chúng.
  2. Để lại các lớp học tốt hơn một mình. Có lẽ chúng được thiết kế tốt và bạn chỉ cần trình bao bọc để làm cho chúng dễ sử dụng hơn. Tôi nghi ngờ đây là trường hợp cho phần lớn dự án của bạn.

Khi bạn hoàn thành tái cấu trúc (nhưng trước khi cam kết với kho lưu trữ), hãy xem lại công việc của bạn và tự hỏi liệu tái cấu trúc của bạn có thực sự là một cải tiến cho khả năng bảo trì và dễ sử dụng hay không.


2
Cách khác để khiến mọi người suy nghĩ về việc thiết kế các lớp: hãy để họ viết thẻ CRC (Tên lớp, Trách nhiệm, Cộng tác viên) . Nếu một lớp có quá nhiều cộng tác viên hoặc trách nhiệm, rất có thể đó không phải là SRP-ish. Nói cách khác, tất cả các văn bản phải phù hợp với thẻ chỉ mục, hoặc nếu không nó đang làm quá nhiều.
Spoike

18
Tôi biết súng phun lửa dùng để làm gì, nhưng làm thế nào để bạn câu cá bằng sào?
R. Martinho Fernandes

13
+1 RẮN là một phương tiện để kết thúc, không phải là kết thúc trong chính nó.
B Bảy

1
+1: Trước đây tôi đã lập luận rằng những thứ như "Luật của Demeter" được đặt tên sai, nó phải là "Dòng hướng dẫn của Demeter". Những điều này sẽ làm việc cho bạn, bạn không nên làm việc cho họ.
Nhị phân nhị phân

2
@EmmadKareem: Đúng là các đối tượng DAO được cho là có một số thuộc tính. Nhưng một lần nữa, có một số thứ mà bạn có thể nhóm lại với nhau trong một thứ đơn giản như một Customerlớp và có nhiều mã có thể duy trì hơn. Xem ví dụ tại đây: codemonkeyism.com/ từ
Spoike

33

Tôi nghĩ rằng trong Tái cấu trúc của Martin Fowler rằng tôi đã từng đọc một quy tắc đối nghịch với SRP, xác định nơi nó sẽ đi quá xa. Có một câu hỏi thứ hai, quan trọng như "mỗi lớp chỉ có một lý do để thay đổi?" và đó là "mỗi thay đổi chỉ ảnh hưởng đến một lớp?"

Nếu câu trả lời cho câu hỏi đầu tiên là, trong mọi trường hợp, "có" nhưng câu hỏi thứ hai là "thậm chí không gần", thì bạn cần xem lại cách bạn thực hiện SRP.

Ví dụ: nếu thêm một trường vào bảng có nghĩa là bạn phải thay đổi một DTO và một lớp trình xác nhận hợp lệ và một lớp kiên trì và một đối tượng mô hình xem và sau đó bạn đã tạo ra một vấn đề. Có lẽ bạn nên suy nghĩ lại về cách bạn đã triển khai SRP.

Có lẽ bạn đã nói rằng việc thêm một trường là lý do để thay đổi đối tượng Khách hàng, nhưng thay đổi lớp kiên trì (giả sử từ tệp XML thành cơ sở dữ liệu) là một lý do khác để thay đổi đối tượng Khách hàng. Vì vậy, bạn quyết định tạo một đối tượng CustomerPersistence là tốt. Nhưng nếu bạn làm như vậy thì việc thêm một trường VẪN yêu cầu thay đổi đối tượng CustomerPersisitence thì vấn đề là gì? Bạn vẫn có một đối tượng với hai lý do để thay đổi - đó không còn là Khách hàng nữa.

Tuy nhiên, nếu bạn giới thiệu ORM, bạn hoàn toàn có thể làm cho các lớp hoạt động sao cho nếu bạn thêm một trường vào DTO, nó sẽ tự động thay đổi SQL được sử dụng để đọc dữ liệu đó. Sau đó, bạn có lý do chính đáng để tách hai mối quan tâm.

Tóm lại, đây là những gì tôi có xu hướng làm: nếu có sự cân bằng thô giữa số lần tôi nói "không, có nhiều hơn một lý do để thay đổi đối tượng này" và số lần tôi nói "không, thay đổi này sẽ ảnh hưởng đến nhiều hơn một đối tượng ", sau đó tôi nghĩ rằng tôi có sự cân bằng giữa SRP và phân mảnh. Nhưng nếu cả hai vẫn còn cao thì tôi bắt đầu tự hỏi liệu có một cách khác mà tôi có thể tách rời mối quan tâm.


+1 cho "mọi thay đổi chỉ ảnh hưởng đến một lớp?"
dj18

Một vấn đề liên quan mà tôi chưa từng thảo luận là nếu các tác vụ được gắn với một thực thể logic bị phân mảnh giữa các lớp khác nhau, thì có thể cần mã để giữ các tham chiếu đến nhiều đối tượng riêng biệt được gắn với cùng một thực thể. Ví dụ, hãy xem xét một lò nung có chức năng "SetHeaterOutput" và "Đo nhiệt độ". Nếu lò được đại diện bởi HeatControl và ThermSensor độc lập, các đối tượng, thì không có gì có thể ngăn đối tượng HeatFeedbackSystem giữ tham chiếu đến lò sưởi một lò và cảm biến nhiệt độ của lò khác.
supercat

1
Nếu thay vào đó, các chức năng đó được kết hợp thành một giao diện IKiln, được thực hiện bởi một đối tượng Kiln, thì HeatFeedbackSystem sẽ chỉ cần giữ một tham chiếu IKiln duy nhất. Nếu cần sử dụng lò nung với cảm biến nhiệt độ hậu mãi độc lập, người ta có thể sử dụng đối tượng CompositeKiln mà nhà xây dựng của họ chấp nhận IHeaterControl và ITem NhiệtSensor và sử dụng chúng để triển khai IKiln, nhưng thành phần lỏng lẻo có chủ ý đó có thể dễ dàng nhận ra trong mã.
supercat

24

Chỉ vì một hệ thống phức tạp không có nghĩa là bạn phải làm cho nó phức tạp . Nếu bạn có một lớp có quá nhiều phụ thuộc (hoặc Cộng tác viên) như thế này:

public class MyAwesomeClass {
    public class MyAwesomeClass(IDependency1 _d1, IDependency2 _d2, ... , IDependency20 _d20) {
      // Assign it all
    }
}

... Sau đó, nó trở nên quá phức tạp và bạn không thực sự theo dõi SRP , phải không? Tôi cá là nếu bạn viết ra những gì MyAwesomeClasstrên thẻ CRC thì nó sẽ không vừa với thẻ chỉ mục hoặc bạn phải viết bằng những chữ cái không thể đọc được.

Những gì bạn có ở đây là các chàng trai của bạn chỉ tuân theo Nguyên tắc phân chia giao diện thay vào đó và có thể đã đưa nó đến một thái cực nhưng đó là một câu chuyện hoàn toàn khác. Bạn có thể lập luận rằng các phụ thuộc là các đối tượng miền (xảy ra) tuy nhiên có một lớp xử lý 20 đối tượng miền cùng một lúc sẽ kéo dài nó quá xa.

TDD sẽ cung cấp cho bạn một chỉ số tốt về mức độ của một lớp học. Nói thẳng ra; nếu một phương thức kiểm tra có mã thiết lập cần mãi mãi để viết (ngay cả khi bạn cấu trúc lại các bài kiểm tra) thì MyAwesomeClasscó lẽ bạn có quá nhiều việc phải làm.

Vậy làm thế nào để bạn giải quyết câu hỏi hóc búa này? Bạn chuyển trách nhiệm sang các lớp khác. Có một số bước bạn có thể thực hiện trên một lớp có vấn đề này:

  1. Xác định tất cả các hành động (hoặc trách nhiệm) mà lớp của bạn thực hiện với các phụ thuộc của nó.
  2. Nhóm các hành động theo phụ thuộc liên quan chặt chẽ.
  3. Tái tổ chức! Tức là tái cấu trúc từng hành động được xác định thành các lớp mới hoặc (quan trọng hơn).

Một ví dụ trừu tượng về tái cấu trúc trách nhiệm

Hãy Clà một lớp mà có một số phụ thuộc D1, D2, D3, D4mà bạn cần phải cấu trúc lại để sử dụng ít hơn. Khi chúng tôi xác định phương thức nào Cgọi vào các phụ thuộc, chúng tôi có thể tạo một danh sách đơn giản về nó:

  • D1- performA(D2),performB()
  • D2 - performD(D1)
  • D3 - performE()
  • D4 - performF(D3)

Nhìn vào danh sách chúng ta có thể thấy điều đó D1D2có liên quan với nhau vì lớp học cần chúng cùng nhau bằng cách nào đó. Chúng ta cũng có thể thấy D4nhu cầu đó D3. Vì vậy, chúng tôi có hai nhóm:

  • Group 1- D1<->D2
  • Group 2- D4->D3

Các nhóm là một chỉ báo rằng lớp hiện có hai trách nhiệm.

  1. Group 1- Một để xử lý việc gọi hai đối tượng cần nhau. Có lẽ bạn có thể để lớp của mình Cloại bỏ nhu cầu xử lý cả hai phụ thuộc và thay vào đó một trong số họ xử lý các cuộc gọi đó. Trong nhóm này, rõ ràng D1có thể có một tài liệu tham khảo D2.
  2. Group 2- Trách nhiệm khác cần một đối tượng để gọi một đối tượng khác. Không thể D4xử lý D3thay vì lớp học của bạn? Sau đó, chúng ta có thể loại bỏ D3khỏi lớp Cbằng cách D4thực hiện các cuộc gọi thay thế.

Đừng lấy câu trả lời của tôi như đặt trong đá vì ví dụ này rất trừu tượng và đưa ra rất nhiều giả định. Tôi khá chắc chắn có nhiều cách để cấu trúc lại điều này, nhưng ít nhất các bước có thể giúp bạn có được một quy trình nào đó để di chuyển các trách nhiệm xung quanh thay vì chia tách các lớp.


Biên tập:

Trong số các ý kiến @Emmad Karem nói:

"Nếu lớp của bạn có 20 tham số trong hàm tạo, có vẻ như nhóm của bạn không biết SRP là gì. Nếu bạn có một lớp chỉ có một thứ, làm thế nào nó có 20 phụ thuộc?" - Tôi nghĩ rằng Nếu bạn có một lớp Khách hàng, không có gì lạ khi có 20 tham số trong hàm tạo.

Đúng là các đối tượng DAO có xu hướng có rất nhiều tham số, mà bạn phải đặt trong hàm tạo của mình và các tham số thường là các kiểu đơn giản như chuỗi. Tuy nhiên, trong ví dụ về một Customerlớp, bạn vẫn có thể nhóm các thuộc tính của nó bên trong các lớp khác để làm cho mọi thứ đơn giản hơn. Chẳng hạn như có một Addresslớp với các đường phố và một Zipcodelớp có chứa mã zip và cũng sẽ xử lý logic nghiệp vụ như xác thực dữ liệu:

public class Address {
    private String street1;
    //...

    private Zipcode zipcode;

    // easy to extend
    public bool isValid() {
        return zipcode.isValid();
    }
}

public class Zipcode {
    private string zipcode;
    public bool isValid() {
        // return regex match that zipcode contains numbers
    }
}

Điều này được thảo luận thêm trong bài đăng trên blog "Không bao giờ, không bao giờ, không bao giờ sử dụng Chuỗi trong Java (hoặc ít nhất là thường xuyên)" . Thay thế cho việc sử dụng các hàm tạo hoặc các phương thức tĩnh để làm cho các đối tượng phụ dễ tạo hơn, bạn có thể sử dụng một mẫu xây dựng chất lỏng .


+1: Câu trả lời tuyệt vời! Nhóm là IMO một cơ chế rất mạnh bởi vì bạn có thể áp dụng nhóm theo cách đệ quy. Nói rất đại khái, với n lớp trừu tượng, bạn có thể sắp xếp 2 ^ n mục.
Giorgio

+1: Một vài đoạn đầu tiên của bạn tổng hợp chính xác những gì nhóm của tôi đang phải đối mặt. "Đối tượng kinh doanh" thực sự là các đối tượng dịch vụ và mã thiết lập thử nghiệm đơn vị gây khó chịu khi viết. Tôi biết rằng chúng tôi đã gặp sự cố khi các cuộc gọi lớp dịch vụ của chúng tôi sẽ chứa một dòng mã; một cuộc gọi đến một phương thức lớp kinh doanh.
Người đàn ông

3

Tôi đồng ý với tất cả các câu trả lời về SRP và làm thế nào nó có thể được đưa đi quá xa. Trong bài đăng của bạn, bạn đề cập rằng do "tái cấu trúc quá mức" để tuân thủ SRP, bạn thấy việc đóng gói bị phá vỡ hoặc bị sửa đổi. Một điều đã làm việc cho tôi là luôn luôn tuân thủ những điều cơ bản và làm chính xác những gì được yêu cầu để đáp ứng kết thúc.

Khi làm việc với các hệ thống Legacy, "sự nhiệt tình" để sửa chữa mọi thứ để làm cho nó tốt hơn thường khá cao trong Nhóm dẫn, đặc biệt là những người mới với vai trò đó. RẮN, chỉ không có SRP - Đó chỉ là S. Hãy chắc chắn rằng nếu bạn đang theo dõi RẮN, bạn cũng đừng quên OLID.

Tôi đang làm việc trên một hệ thống Legacy ngay bây giờ và chúng tôi bắt đầu đi xuống một con đường tương tự ngay từ đầu. Điều làm việc cho chúng tôi là một quyết định tập thể để làm cho tốt nhất của cả hai thế giới - RẮN và KISS (Giữ cho nó đơn giản ngu ngốc). Chúng tôi đã thảo luận chung về những thay đổi lớn đối với cấu trúc mã và áp dụng ý thức chung trong việc áp dụng các nguyên tắc phát triển khác nhau. Chúng tuyệt vời như những hướng dẫn không phải là "Luật phát triển S / W". Nhóm không chỉ là về Trưởng nhóm - mà còn về tất cả các nhà phát triển trong nhóm. Điều luôn luôn làm việc cho tôi là đưa mọi người vào phòng và đưa ra một bộ hướng dẫn chung mà toàn bộ nhóm của bạn đồng ý tuân theo.

Về cách khắc phục tình trạng hiện tại của bạn, nếu bạn sử dụng VCS và chưa thêm quá nhiều tính năng mới vào ứng dụng của mình, bạn luôn có thể quay lại phiên bản mã mà toàn bộ nhóm cho là dễ hiểu, dễ đọc và có thể duy trì. Đúng! Tôi đang yêu cầu bạn vứt bỏ công việc và bắt đầu lại từ đầu. Điều này tốt hơn là cố gắng "sửa chữa" một cái gì đó đã bị hỏng và chuyển nó trở lại một cái gì đó đã tồn tại.


3

Câu trả lời là khả năng duy trì và tính rõ ràng của mã trên tất cả các thứ khác. Đối với tôi điều đó có nghĩa là viết ít mã hơn , không nhiều hơn. Ít trừu tượng hơn, ít giao diện hơn, ít tùy chọn hơn, ít tham số hơn.

Bất cứ khi nào tôi đánh giá cấu trúc lại mã, hoặc thêm một tính năng mới, tôi nghĩ về việc sẽ cần bao nhiêu bản tóm tắt so với logic thực tế. Nếu câu trả lời là hơn 50%, điều đó có nghĩa là tôi đang nghĩ quá nhiều.

Trên đầu trang của SRP, có nhiều phong cách phát triển khác. Trong trường hợp của bạn, âm thanh của nó giống như YAGNI chắc chắn là thiếu.


3

Rất nhiều câu trả lời ở đây thực sự tốt nhưng tập trung vào khía cạnh kỹ thuật của vấn đề này. Tôi chỉ đơn giản là thêm rằng có vẻ như các nhà phát triển cố gắng theo dõi âm thanh SRP giống như họ thực sự vi phạm SRP.

Bạn có thể thấy blog của Bob ở đây về tình huống này, nhưng anh ta lập luận rằng nếu một trách nhiệm được bôi nhọ qua nhiều lớp thì trách nhiệm SRP bị vi phạm vì các lớp đó thay đổi song song. Tôi nghi ngờ nhà phát triển của bạn sẽ thực sự thích thiết kế ở đầu blog của Bob và có thể hơi thất vọng khi thấy nó bị xé toạc. Đặc biệt bởi vì nó vi phạm "Nguyên tắc đóng cửa chung" - những thứ thay đổi cùng ở lại với nhau.

Hãy nhớ rằng SRP đề cập đến "lý do thay đổi" chứ không phải "làm một việc" và bạn không cần quan tâm đến lý do thay đổi đó cho đến khi thay đổi thực sự xảy ra. Anh chàng thứ hai trả tiền cho sự trừu tượng.

Bây giờ có vấn đề thứ hai - "người ủng hộ mạnh mẽ cho sự phát triển RẮN". Có vẻ như bạn không có mối quan hệ tuyệt vời với nhà phát triển này, vì vậy mọi nỗ lực thuyết phục anh ấy / cô ấy về các vấn đề trong cơ sở mã đều bị cản trở. Bạn sẽ cần sửa chữa mối quan hệ để bạn có thể có một cuộc thảo luận thực sự về các vấn đề. Những gì tôi muốn giới thiệu là bia.

Không nghiêm túc - nếu bạn không uống đầu vào quán cà phê. Ra khỏi văn phòng và một nơi nào đó thư giãn, nơi bạn có thể nói về những thứ này một cách không chính thức. Thay vì cố gắng giành chiến thắng trong một cuộc họp, mà bạn sẽ không có cuộc thảo luận nào đó vui vẻ. Hãy cố gắng nhận ra rằng nhà phát triển này, người đang điều khiển bạn, là một người hoạt động thực sự, người đang cố gắng đưa phần mềm "ra khỏi cửa" và không muốn gửi tin tào lao. Vì bạn có thể chia sẻ điểm chung đó, bạn có thể bắt đầu thảo luận về cách cải thiện thiết kế trong khi vẫn tuân thủ SRP.

Nếu cả hai bạn có thể thừa nhận rằng SRP là một điều tốt, rằng bạn chỉ diễn giải các khía cạnh khác nhau, có lẽ bạn có thể bắt đầu có những cuộc trò chuyện hữu ích.


-1

Tôi đồng ý với quyết định của nhóm trưởng của bạn [update = 2012.05.31] rằng SRP nói chung là một suy nghĩ tốt. Nhưng tôi hoàn toàn đồng ý với nhận xét của @ Spoike rằng một nhà xây dựng với 20 đối số giao diện là rất nhiều. [/ Update]:

Giới thiệu SRP với IoC chuyển sự phức tạp từ một "lớp đa trách nhiệm" sang nhiều lớp srp và khởi tạo phức tạp hơn nhiều vì lợi ích của

  • kiểm tra đơn vị / tdd dễ dàng hơn (kiểm tra một lớp srp một cách cô lập)
  • nhưng với chi phí
    • một khởi tạo và tích hợp mã khác nhiều hơn và
    • gỡ lỗi khác
    • phân mảnh (= phân phối mã trên một số tệp / thư mục)

Tôi sợ bạn không thể giảm mã hóa mà không hy sinh srp.

Nhưng bạn có thể "giảm bớt nỗi đau" của quá trình mã hóa bằng cách triển khai một lớp đường cú pháp che giấu sự phức tạp của việc khởi tạo trong một hàm tạo.

   class MySrpClass {
      MySrpClass(Interface1 parm1, Interface2 param2, .... Interface20 param2) {
      }
   } 

   class MySyntaxSugarClass : MySrpClass {
      MySyntaxSugarClass() {
         super(new MyInterface1Implementation(), new MyImpl2(), ....)
      }
   }

2
Tôi tin rằng 20 giao diện là một chỉ số mà lớp có quá nhiều việc phải làm. Tức là có 20 lý do để nó thay đổi, đó là vi phạm SRP. Chỉ vì hệ thống phức tạp không có nghĩa là nó phải phức tạp.
Spoike
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.