Có phải các lớp chỉ có một phương thức (công khai) là một vấn đề?


51

Tôi hiện đang làm việc trong một dự án phần mềm thực hiện nén và lập chỉ mục trên các đoạn phim giám sát video. Quá trình nén hoạt động bằng cách tách các đối tượng nền và tiền cảnh, sau đó lưu nền dưới dạng hình ảnh tĩnh và tiền cảnh dưới dạng sprite.

Gần đây, tôi đã bắt tay vào việc xem xét một số lớp mà tôi đã thiết kế cho dự án.

Tôi nhận thấy rằng có nhiều lớp chỉ có một phương thức công khai duy nhất. Một số trong các lớp này là:

  • VideoCompressor (với compressphương thức lấy một video đầu vào loại RawVideovà trả về một video đầu ra loại CompressedVideo).
  • VideoSplitter (với splitphương thức lấy một video đầu vào loại RawVideovà trả về một vectơ gồm 2 video đầu ra, mỗi loại RawVideo).
  • Video Indexer (với một indexphương thức lấy một video đầu vào loại RawVideovà trả về một chỉ mục video loại VideoIndex).

Tôi thấy mình instantiating mỗi lớp chỉ để thực hiện cuộc gọi như VideoCompressor.compress(...), VideoSplitter.split(...), VideoIndexer.index(...).

Nhìn bề ngoài, tôi nghĩ rằng các tên lớp đủ để mô tả chức năng dự định của chúng và chúng thực sự là danh từ. Tương ứng, phương pháp của họ cũng là động từ.

Đây thực sự là một vấn đề?


14
Nó phụ thuộc vào ngôn ngữ. Trong một ngôn ngữ đa mô hình như C ++ hoặc Python, các lớp này không có doanh nghiệp tồn tại: "phương thức" của chúng phải là các hàm miễn phí.

3
@delnan: ngay cả trong C ++, bạn thường sử dụng các lớp để tạo mô-đun, ngay cả khi bạn không cần "khả năng OO" đầy đủ. Thật vậy, có một cách khác là sử dụng các không gian tên thay vì nhóm "các hàm miễn phí" lại với nhau thành một mô-đun, nhưng tôi không thấy bất kỳ lợi thế nào trong đó.
Doc Brown

5
@DocBrown: C ++ có không gian tên cho điều đó. Trong thực tế trong C ++ hiện đại, bạn thường sử dụng các hàm miễn phí cho các phương thức, bởi vì chúng có thể bị quá tải (tĩnh) cho tất cả các đối số trong khi các phương thức chỉ có thể bị quá tải cho người truy cập.
Jan Hudec

2
@DocBrown: Đó là một cốt lõi của câu hỏi. Các mô-đun sử dụng không gian tên chỉ có một phương thức "bên ngoài" là hoàn toàn tốt khi chức năng đủ phức tạp. Bởi vì không gian tên không giả vờ đại diện cho bất cứ điều gì và không giả vờ là hướng đối tượng. Các lớp học, nhưng các lớp như thế này thực sự chỉ là không gian tên. Tất nhiên trong Java bạn không thể có một hàm, vì vậy đây là kết quả. Xấu hổ về Java.
Jan Hudec

2
Liên quan (gần như một bản sao): lập trình
viên.stackexchange.com / q / 175070/33843

Câu trả lời:


87

Không, đây không phải là một vấn đề, hoàn toàn ngược lại. Đó là một dấu hiệu của mô-đun và trách nhiệm rõ ràng của lớp. Giao diện nạc dễ nắm bắt từ quan điểm của người dùng của lớp đó và nó sẽ khuyến khích khớp nối lỏng lẻo. Điều này có nhiều lợi thế nhưng hầu như không có nhược điểm. Tôi muốn nhiều thành phần sẽ được thiết kế theo cách đó!


6
Đây là câu trả lời đúng và tôi đã nâng cao nó, nhưng bạn có thể làm cho nó tốt hơn bằng cách giải thích một số lợi thế. Tôi nghĩ rằng những gì bản năng của OP đang nói với anh ta là một vấn đề là một thứ khác ... đó là, VideoCompressor thực sự là một giao diện. Mp4VideoCompressor là một lớp và có thể hoán đổi với một VideoCompressor khác mà không cần sao chép mã cho VideoSplitter sang một lớp mới.
pdr

1
Xin lỗi nhưng bạn đã sai. Một lớp với một phương thức duy nhất chỉ nên là một hàm độc lập.
Miles Rout

3
@MilesRout: bình luận của bạn cho thấy bạn đã hiểu nhầm câu hỏi - OP đã viết về một lớp với một phương thức công khai, không phải bằng một phương thức (và thực sự anh ta có nghĩa là một lớp có nhiều phương thức riêng tư, như anh ta đã nói với chúng tôi ở đây trong một bình luận).
Doc Brown

2
"Một lớp với một phương thức duy nhất chỉ nên là một hàm độc lập." Giả định chung về phương thức đó là gì. Tôi có một lớp học với một phương pháp công khai. BEHIND IT là nhiều phương thức trong lớp đó cộng với 5 lớp khác hoàn toàn không có ý tưởng nào về máy khách. Ứng dụng tuyệt vời của SRP sẽ mang lại giao diện đơn giản, sạch sẽ của cấu trúc lớp được phân lớp, với sự đơn giản đó biểu hiện cho đến đỉnh.
radarbob

2
@Andy: câu hỏi là "đây có phải là vấn đề không" và không "điều này có phù hợp với định nghĩa OO cụ thể không". Hơn nữa, hoàn toàn không có dấu hiệu nào trong câu hỏi OP có nghĩa là các lớp không có trạng thái.
Doc Brown

26

Nó không còn là đối tượng hướng. Bởi vì các lớp đó không đại diện cho bất cứ điều gì, chúng chỉ là các tàu cho các chức năng.

Điều đó không có nghĩa là nó sai. Nếu chức năng đủ phức tạp hoặc khi nó chung chung (nghĩa là các đối số là giao diện, không phải là loại cuối cùng cụ thể), thì nên đặt chức năng đó trong mô-đun riêng biệt .

Từ đó nó phụ thuộc vào ngôn ngữ của bạn. Nếu ngôn ngữ có chức năng miễn phí, chúng phải là mô-đun xuất các chức năng. Tại sao nó giả vờ là một lớp học khi nó không. Nếu ngôn ngữ không có các hàm miễn phí như Java, thì bạn tạo các lớp với phương thức chung duy nhất. Vâng, điều đó chỉ cho thấy các giới hạn của thiết kế hướng đối tượng. Đôi khi chức năng chỉ đơn giản là phù hợp hơn.

Có một trường hợp khi bạn có thể cần một lớp với phương thức chung duy nhất bởi vì nó phải thực hiện giao diện với phương thức chung duy nhất. Có thể là cho mẫu quan sát hoặc tiêm phụ thuộc hoặc bất cứ điều gì. Ở đây nó một lần nữa phụ thuộc vào ngôn ngữ. Trong các ngôn ngữ có hàm functor hạng nhất (C ++ ( std::functionhoặc tham số mẫu), C # (ủy nhiệm), Python, Perl, Ruby ( proc), Lisp, Haskell, ...) các mẫu này sử dụng các loại hàm và không cần các lớp. Java không (chưa, trong phiên bản 8) có các kiểu hàm, vì vậy bạn sử dụng các giao diện phương thức đơn và các lớp phương thức đơn tương ứng.

Tất nhiên tôi không ủng hộ việc viết một chức năng lớn. Nó nên có các chương trình con riêng tư, nhưng chúng có thể là riêng tư đối với tệp thực hiện (không gian tên tĩnh hoặc ẩn danh ở cấp độ tệp trong C ++) hoặc trong lớp trình trợ giúp riêng chỉ được khởi tạo bên trong hàm công khai ( Để lưu trữ dữ liệu hay không? ).


12
"Tại sao lại giả vờ đó là một lớp học khi nó không." Có một đối tượng thay vì một chức năng miễn phí cho phép trạng thái và phân nhóm. Điều đó có thể chứng minh giá trị trong một thế giới nơi yêu cầu thay đổi. Sớm hay muộn cũng cần phải chơi với các cài đặt nén video hoặc để cung cấp các thuật toán nén thay thế. Trước đó, từ "class" chỉ đơn giản cho chúng ta biết rằng chức năng này thuộc về một mô-đun phần mềm có thể mở rộng và có thể thay thế dễ dàng với trách nhiệm rõ ràng. Đó không phải là những gì OO thực sự nhắm đến sao?
ĐẾN TỪ

1
Chà, nếu nó chỉ có một phương thức công khai (và loại ngụ ý không có phương thức được bảo vệ), thì nó thực sự không thể được mở rộng. Tất nhiên, việc đóng gói các tham số nén có thể có ý nghĩa trong trường hợp nó trở thành đối tượng hàm (một số ngôn ngữ có hỗ trợ riêng cho các tham số đó, một số ngôn ngữ không).
Jan Hudec

3
Đây là một kết nối cơ bản giữa các đối tượng và các hàm: một hàm là đẳng cấu với một đối tượng với một phương thức duy nhất và không có các trường. Một bao đóng là đẳng cấu với một đối tượng với một phương thức duy nhất và một số trường. Hàm chọn trả về một trong một số hàm mà tất cả đóng trên cùng một bộ biến là đẳng cấu với một đối tượng. (Trên thực tế, đây là cách các đối tượng được mã hóa bằng JavaScript, ngoại trừ bạn sử dụng cấu trúc dữ liệu từ điển thay vì chức năng chọn.)
Jörg W Mittag

4
"Nó không còn hướng đối tượng nữa. Bởi vì các lớp đó không đại diện cho bất cứ điều gì, chúng chỉ là các mạch cho các chức năng." - Cái này sai. Tôi sẽ tranh luận cách tiếp cận này là hướng đối tượng THÊM. OO không có nghĩa là nó đại diện cho một đối tượng trong thế giới thực. Một lượng lớn giao dịch lập trình với các khái niệm trừu tượng, nhưng điều này có nghĩa là bạn không thể áp dụng cách tiếp cận OO để giải quyết nó? Chắc chắn không phải. Đó là nhiều hơn về mô-đun và trừu tượng. Mỗi đối tượng có một trách nhiệm duy nhất. Điều này giúp bạn dễ dàng quấn đầu quanh chương trình và thay đổi. Không đủ không gian để liệt kê nhiều lợi ích của OOP.
Despertar

2
@Phoshi: Vâng, tôi hiểu. Tôi không bao giờ tuyên bố rằng một phương pháp chức năng sẽ không hoạt động tốt. Tuy nhiên, đó rõ ràng không phải là chủ đề. Máy nén video hoặc máy phát video hoặc bất cứ thứ gì vẫn là một ứng cử viên hoàn toàn hợp lệ cho một đối tượng.
ĐẾN TỪ

13

Có thể có lý do để trích xuất một phương thức nhất định vào một lớp chuyên dụng. Một trong những lý do đó là cho phép tiêm Dependency.

Hãy tưởng tượng bạn có một lớp được gọi là VideoExporter, cuối cùng, sẽ có thể nén video. Một cách sạch sẽ là có một giao diện:

interface IVideoCompressor
{
    Stream compress(Video video);
}

sẽ được thực hiện như thế này:

class MpegVideoCompressor : IVideoCompressor
{
    // ...
}

class FlashVideoCompressor : IVideoCompressor
{
    // ...
}

và được sử dụng như thế này:

class VideoExporter
{
    // ...
    void export(Destination destination, IVideoCompressor compressor)
    {
        // ...
        destination = compressor(this.source);
        // ...
    }
    // ...
}

Một thay thế xấu sẽ là có một VideoExporterphương pháp công khai và thực hiện tất cả các công việc, bao gồm cả nén. Nó sẽ nhanh chóng trở thành một cơn ác mộng bảo trì, khiến việc thêm hỗ trợ cho các định dạng video khác trở nên khó khăn.


2
Câu trả lời của bạn không phân biệt giữa phương pháp công cộng và riêng tư. Nó có thể được hiểu là một khuyến nghị cho việc đặt tất cả mã của một lớp chỉ một phương thức, nhưng tôi đoán đó không phải là ý bạn?
Doc Brown

2
@DocBrown: Các phương thức riêng tư không liên quan đến câu hỏi này. Họ có thể được đưa vào lớp người trợ giúp nội bộ hoặc bất cứ điều gì.
Jan Hudec

2
@JanHudec: hiện tại văn bản là "Một lựa chọn không tốt sẽ có một VideoExporter có nhiều phương thức" - nhưng nó phải là "Một lựa chọn không tốt sẽ có một VideoExporter có nhiều phương thức công khai ".
Doc Brown

@DocBrown: Đồng ý ở đây.
Jan Hudec

2
@DocBrown: cảm ơn bạn đã nhận xét của bạn. Tôi chỉnh sửa câu trả lời của tôi. Ban đầu, tôi nghĩ rằng người ta cho rằng câu hỏi (và vì vậy câu trả lời của tôi) chỉ là về phương pháp công khai. Có vẻ như nó không rõ ràng.
Arseni Mourzenko

6

Đây là một dấu hiệu cho thấy bạn muốn truyền các hàm làm đối số cho các hàm khác. Tôi đoán ngôn ngữ của bạn (Java?) Không hỗ trợ ngôn ngữ đó; nếu đó là trường hợp, nó không phải là một thất bại trong thiết kế của bạn vì nó là một thiếu sót trong ngôn ngữ của bạn lựa chọn. Đây là một trong những vấn đề lớn nhất với các ngôn ngữ khẳng định rằng mọi thứ phải là một lớp.

Nếu bạn không thực sự chuyển các hàm giả này xung quanh thì bạn chỉ muốn một hàm tự do / tĩnh.


1
Kể từ Java 8, bạn có lambdas, vì vậy bạn có thể truyền các hàm.
Silviu Burcea

Điểm công bằng, nhưng điều đó sẽ không được phát hành chính thức trong một thời gian ngắn nữa, và một số nơi làm việc chậm chuyển sang các phiên bản mới hơn.
Doval

Ngày phát hành là vào tháng ba. Ngoài ra, các bản dựng EAP rất phổ biến cho JDK 8 :)
Silviu Burcea

Mặc dù, vì lambdas Java 8 chỉ đơn giản là một cách tốc ký để xác định các đối tượng chỉ bằng một phương thức công khai, ngoài việc tiết kiệm một chút mã soạn sẵn, chúng không tạo ra sự khác biệt nào ở đây.
Jules

5

Tôi biết tôi đến bữa tiệc muộn nhưng dường như mọi người đã bỏ lỡ để chỉ ra điều này:

Đây là một mẫu thiết kế nổi tiếng được gọi là: Mẫu chiến lược .

Mẫu chiến lược được sử dụng khi có một số chiến lược khả thi để giải quyết vấn đề phụ. Thông thường, bạn xác định một giao diện thực thi hợp đồng trên tất cả các triển khai và sau đó sử dụng một số hình thức của Dependency Injection để cung cấp chiến lược cụ thể cho bạn.

Ví dụ trong trường hợp này bạn có thể có interface VideoCompressorvà sau đó có một số triển khai thay thế chẳng hạn class H264Compressor implements VideoCompressorclass XVidCompressor implements VideoCompressor. OP không rõ ràng rằng có một giao diện liên quan, ngay cả khi không có, có thể chỉ đơn giản là tác giả ban đầu đã mở cửa để thực hiện mô hình chiến lược nếu cần. Mà trong và của chính nó là thiết kế tốt quá.

Vấn đề mà OP liên tục thấy mình bắt đầu các lớp để gọi một phương thức là một vấn đề với việc cô ấy không sử dụng phép tiêm phụ thuộc và mô hình chiến lược một cách chính xác. Thay vì khởi tạo nó ở nơi bạn cần, lớp chứa nên có một thành viên với đối tượng chiến lược. Và thành viên này nên được tiêm, ví dụ như trong hàm tạo.

Trong nhiều trường hợp, mẫu chiến lược dẫn đến các lớp giao diện (như bạn đang hiển thị) chỉ bằng một doStuff(...)phương thức duy nhất .


1
public interface IVideoProcessor
{
   void Split();

   void Compress();

   void Index();
}

Những gì bạn đã có là mô-đun và điều đó tốt, nhưng nếu bạn nhóm các trách nhiệm này vào IVideoProcessor, điều đó có thể có ý nghĩa hơn từ quan điểm của DDD.

Mặt khác, nếu chia tách, nén và lập chỉ mục không liên quan theo bất kỳ cách nào, thì tôi sẽ giữ chúng như các thành phần riêng biệt.


Vì lý do cho mỗi chức năng này cần thay đổi là hơi khác nhau, tôi cho rằng việc đặt chúng cùng nhau như thế này sẽ vi phạm SRP.
Jules

0

Đó là một vấn đề - bạn đang làm việc từ khía cạnh chức năng của thiết kế, chứ không phải là dữ liệu. Những gì bạn thực sự có là 3 chức năng độc lập đã được OO-ified.

Ví dụ: bạn có lớp VideoCompressor. Tại sao bạn làm việc với một lớp được thiết kế để nén video - tại sao bạn không có lớp Video với các phương thức trên đó để nén dữ liệu (video) mà mỗi đối tượng thuộc loại này chứa?

Khi thiết kế các hệ thống OO, tốt nhất là tạo các lớp đại diện cho các đối tượng, thay vì các lớp đại diện cho các hoạt động mà bạn có thể áp dụng. Vào thời xưa, các lớp được gọi là các loại - OO là một cách để mở rộng ngôn ngữ với sự hỗ trợ cho các loại dữ liệu mới. Nếu bạn nghĩ về OO như thế này, bạn sẽ có một cách tốt hơn để thiết kế các lớp học của mình.

BIÊN TẬP:

hãy để tôi cố gắng giải thích bản thân tốt hơn một chút, hãy tưởng tượng một lớp chuỗi có phương thức concat. Bạn có thể triển khai một thứ như vậy trong đó mỗi đối tượng được khởi tạo từ lớp chứa dữ liệu chuỗi, vì vậy bạn có thể nói

string mystring("Hello"); 
mystring.concat("World");

nhưng OP muốn nó hoạt động như thế này:

string mystring();
string result = mystring.concat("Hello", "World");

bây giờ có những nơi mà một lớp có thể được sử dụng để chứa một tập hợp các hàm liên quan, nhưng đó không phải là OO, đó là cách sử dụng các tính năng OO của ngôn ngữ để giúp quản lý cơ sở mã của bạn tốt hơn, nhưng không có cách nào khác của "Thiết kế OO". Đối tượng trong các trường hợp như vậy là hoàn toàn nhân tạo, chỉ đơn giản được sử dụng như thế này vì ngôn ngữ không cung cấp bất cứ điều gì tốt hơn để quản lý loại vấn đề này. ví dụ. Trong các ngôn ngữ như C #, bạn sẽ sử dụng một lớp tĩnh để cung cấp chức năng này - nó sử dụng lại cơ chế lớp, nhưng bạn không còn cần phải khởi tạo một đối tượng chỉ để gọi các phương thức trên nó. Bạn kết thúc với các phương pháp string.IsNullOrEmpty(mystring)mà tôi nghĩ là kém so với mystring.isNullOrEmpty().

Vì vậy, nếu bất cứ ai hỏi "làm thế nào để tôi thiết kế các lớp của mình", tôi khuyên bạn nên nghĩ về dữ liệu mà lớp sẽ chứa thay vì các hàm mà nó chứa. Nếu bạn chọn "một lớp là một loạt các phương thức", thì cuối cùng bạn sẽ viết mã kiểu "C tốt hơn". (điều này không nhất thiết là điều xấu nếu bạn đang cải thiện mã C) nhưng nó sẽ không cung cấp cho bạn chương trình được thiết kế OO tốt nhất.


9
-1, tôi hoàn toàn không đồng ý. Người mới bắt đầu Thiết kế OO chỉ hoạt động với các đối tượng dữ liệu như a Videovà có xu hướng làm mờ các lớp như vậy với chức năng, thường kết thúc bằng mã lộn xộn với> 10K LỘC mỗi lớp. Thiết kế OO nâng cao phá vỡ chức năng xuống các đơn vị nhỏ hơn như VideoCompressor(và cho phép một Videolớp chỉ là một lớp dữ liệu hoặc mặt tiền cho VideoCompressor).
Doc Brown

5
@DocBrown: Tại thời điểm đó, nó không còn là một thiết kế hướng đối tượng, bởi vì VideoCompressornó không đại diện cho một đối tượng . Không có gì sai với điều đó, chỉ cho thấy giới hạn của thiết kế hướng đối tượng.
Jan Hudec

3
ah nhưng người mới bắt đầu OO trong đó 1 chức năng được chuyển thành một lớp hoàn toàn không phải là OO và chỉ khuyến khích việc tách rời lớn kết thúc trong hàng ngàn tệp của lớp mà không ai có thể duy trì. Tôi nghĩ tốt nhất nên nghĩ về một lớp là "trình bao bọc dữ liệu" chứ không phải là "trình bao bọc chức năng", điều đó sẽ giúp người mới bắt đầu hiểu rõ hơn về cách nghĩ về các chương trình OO.
gbjbaanb

4
@DocBrown thực sự làm nổi bật mối quan tâm của tôi; Tôi thực sự có một Videolớp, nhưng phương thức nén không có cách nào tầm thường, vì vậy tôi thực sự sẽ chia compressphương thức thành nhiều phương thức riêng tư khác. Đây là một phần lý do cho câu hỏi của tôi, sau khi đọc Đừng tạo các lớp động từ
yjwong

2
Tôi nghĩ rằng có thể ổn khi có một Videolớp, nhưng nó sẽ bao gồm các lớp a VideoCompressor, a VideoSplittervà các lớp liên quan khác, ở dạng OO tốt, nên là các lớp riêng lẻ có tính gắn kết cao.
Eric King

-1

Các ISP (nguyên tắc phân giao diện) nói rằng không có khách hàng nên buộc phải phụ thuộc vào phương pháp nó không sử dụng. Những lợi ích là nhiều và rõ ràng. Cách tiếp cận của bạn hoàn toàn tôn trọng ISP, và điều đó tốt.

Một cách tiếp cận khác cũng tôn trọng ISP, ví dụ, tạo một giao diện cho mỗi phương thức (hoặc tập hợp các phương thức có độ gắn kết cao) và sau đó có một lớp duy nhất thực hiện tất cả các giao diện đó. Cho dù đây là hay không một giải pháp tốt hơn phụ thuộc vào kịch bản. Lợi ích của việc này là, khi sử dụng phép nội xạ phụ thuộc, bạn có thể có một ứng dụng khách với các cộng tác viên khác nhau (mỗi người trên một giao diện) nhưng cuối cùng tất cả các cộng tác viên sẽ trỏ đến cùng một đối tượng.

Nhân tiện, bạn đã nói

Tôi thấy mình đang bắt đầu mỗi lớp

, các lớp này dường như là các dịch vụ (và do đó không trạng thái). Bạn đã nghĩ về việc làm cho họ singletons?



3
Đối với phần còn lại trong khi nguyên tắc phân tách giao diện là một mô hình tốt, câu hỏi này là về việc triển khai, không phải các giao diện, vì vậy tôi không chắc nó có liên quan.
Jan Hudec

3
Tôi sẽ không tham gia để thảo luận về việc singleton là một mô hình hay một phản mẫu. Tôi đã đề xuất một giải pháp khả thi (thậm chí nó có một cái tên) cho vấn đề của nó, tùy thuộc vào anh ta quyết định xem nó có phù hợp hay không.
dieeimt Khung

Về việc ISP có liên quan hay không, tốt, chủ đề của câu hỏi là "các lớp chỉ có một phương thức duy nhất là một vấn đề?", Ngược lại đó là một lớp có nhiều phương thức, trở thành vấn đề ngay khi bạn thực hiện khách hàng phụ thuộc trực tiếp vào nó ... chính xác là ví dụ xerox của Robert Martin mà anh ta đã đưa ra để xây dựng ISP.
dieeimt Khung

-1

Vâng, có một vấn đề. Nhưng không nghiêm trọng. Tôi có nghĩa là bạn có thể cấu trúc mã của bạn như thế này và sẽ không có gì xấu xảy ra, nó có thể được duy trì. Nhưng có một số điểm yếu cho loại cấu trúc đó. Ví dụ, hãy xem xét nếu đại diện cho video của bạn (trong trường hợp của bạn, nó được nhóm trong lớp RawVideo) thay đổi, bạn sẽ cần cập nhật tất cả các lớp hoạt động của mình. Hoặc xem xét rằng bạn có thể có nhiều đại diện cho video khác nhau trong thời gian chạy. Sau đó, bạn sẽ phải khớp đại diện với lớp "hoạt động" cụ thể. Ngoài ra, về mặt chủ quan, thật khó chịu khi phải kéo theo một phụ thuộc cho mỗi thao tác bạn muốn thực hiện trên smth. và để cập nhật danh sách các phụ thuộc được chuyển qua mỗi khi bạn quyết định rằng hoạt động không còn cần thiết hoặc bạn cần hoạt động mới.

Ngoài ra, đó thực sự là một vi phạm SRP. Một số người chỉ coi SRP là một hướng dẫn để phân chia trách nhiệm (và đưa nó đi xa bằng cách coi mỗi hoạt động là một trách nhiệm riêng biệt) nhưng họ quên rằng SRP cũng là một hướng dẫn để phân nhóm trách nhiệm. Và theo trách nhiệm của SRP thay đổi vì cùng một lý do nên được nhóm lại với nhau để nếu thay đổi xảy ra, nó được tập trung vào càng ít lớp / mô-đun càng tốt. Đối với các lớp lớn, không có vấn đề gì khi có nhiều thuật toán trong cùng một lớp miễn là các thuật toán đó có liên quan (nghĩa là chia sẻ một số kiến ​​thức không nên biết bên ngoài lớp đó). Vấn đề là các lớp lớn có các thuật toán không liên quan theo bất kỳ cách nào và thay đổi / thay đổi vì những lý do khác nhau.

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.