2012-05-16 31 views
23

Ai đó có thể cho tôi một ví dụ về Nguyên tắc về Trách nhiệm duy nhất không? Tôi đang cố gắng hiểu ý nghĩa của nó, trong thực tế, cho một lớp học có một trách nhiệm duy nhất vì tôi sợ rằng tôi có thể phá vỡ quy tắc này hàng ngày.Ví dụ về nguyên tắc về trách nhiệm duy nhất là gì?

+0

Hãy xem ở đây: http://stackoverflow.com/questions/659232/it-this-an-example-of-the-single-responsibility -principle –

+0

http://www.phpfreaks.com/tutorial/oo-php-part-2-boring-oo-principles –

+0

Btw, bạn đã không đề cập đến một ví dụ trong một ngôn ngữ cụ thể, vì vậy bất cứ điều gì đi :) –

Trả lời

4

Khám phá Solid description.

Trừ khi bạn yêu cầu điều gì đó cụ thể hơn, sẽ rất khó để trợ giúp thêm.

Trách nhiệm duy nhất là khái niệm về một lớp làm một điều cụ thể (trách nhiệm) và không cố gắng làm nhiều hơn mức cần thiết, mà còn được gọi là sự gắn kết cao.

Lớp học thường không bắt đầu với Low Cohesion, nhưng thường sau một vài bản phát hành và các nhà phát triển khác nhau thêm vào chúng, đột nhiên bạn sẽ nhận thấy rằng nó đã trở thành một quái vật hoặc lớp Thiên Chúa như một số gọi nó. Vì vậy, lớp nên được refactored.

Thật khó để nghĩ ra một ví dụ hay, nhưng tôi có thể nghĩ rằng gần đây sẽ là một lớp mà chúng tôi quản lý các giai đoạn xử lý gói khác nhau, một loại Chain of Responsibility. Ý định ban đầu của lớp này là duy trì một danh sách các giai đoạn và để dàn xếp gọi packetProcess() trên chúng. Vâng, nó đã kết thúc mà mọi người đã thêm bất cứ điều gì để làm với các giai đoạn chế biến (kể từ khi lớp quản lý là một nơi dễ dàng để truy cập vào các giai đoạn) để lớp quản lý này, đặc biệt là cấu hình giai đoạn. Lớp người quản lý không còn có Trách nhiệm một lần nữa, mà thay vào đó, cũng chịu trách nhiệm thực hiện cuộc gọi đến các giai đoạn để thay đổi cấu hình: do đó, sự gắn kết đã bị giảm.

Chúng tôi đã kết thúc việc tái cấu trúc lớp người quản lý, tách tất cả cấu hình sân khấu và đặt nó vào một nhà máy, do đó để người quản lý thực hiện những gì nó dự định làm.

+0

làm bạn có một ví dụ từ công việc của bạn - một ví dụ thế giới thực. –

+4

Tôi đã gặp phải vài tuần trước. Tôi cần một lớp Object Factory để tạo ra các thể hiện của các loại đối tượng khác nhau, sắp xếp chúng, kiên trì với DB, vv. Ý tưởng đầu tiên của tôi là tạo ra một lớp Factory với một phương thức Serialize, nhưng như tôi đã đọc về SRP. ý nghĩa hơn là có một Class dành riêng cho Serialize, một lớp cho các đối tượng Persist trong DB, vv Điều này làm cho ứng dụng của bạn dễ bảo trì hơn và được mô đun hóa hơn. –

+0

@SachinKainth, tôi đã thêm một ví dụ vào câu trả lời của mình. – Brady

24

Cách hiệu quả nhất để chia nhỏ ứng dụng để tạo các lớp học GOD. Đó là các lớp học theo dõi rất nhiều thông tin và có một số trách nhiệm. Một thay đổi mã sẽ rất có thể ảnh hưởng đến các phần khác của lớp và do đó gián tiếp tất cả các lớp khác sử dụng nó. Điều đó dẫn đến một mớ hỗn độn bảo trì lớn hơn vì không ai dám thực hiện bất kỳ thay đổi nào khác ngoài việc thêm chức năng mới vào nó.

Sau đây ví dụ là một lớp nguyên cảo định nghĩa một người, lớp này không nên bao gồm xác nhận email vì đó không liên quan với một người hành vi:

class Person { 
    public name : string; 
    public surname : string; 
    public email : string; 
    constructor(name : string, surname : string, email : string){ 
     this.surname = surname; 
     this.name = name; 
     if(this.validateEmail(email)) { 
      this.email = email; 
     } 
     else { 
      throw new Error("Invalid email!"); 
     } 
    } 
    validateEmail(email : string) { 
     var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i; 
     return re.test(email); 
    } 
    greet() { 
     alert("Hi!"); 
    } 
} 

Chúng tôi có thể cải thiện các lớp trên bằng cách loại bỏ trách nhiệm xác thực email từ lớp Person và tạo một lớp Email mới sẽ có trách nhiệm đó:

class Email { 
    public email : string; 
    constructor(email : string){ 
     if(this.validateEmail(email)) { 
      this.email = email; 
     } 
     else { 
      throw new Error("Invalid email!"); 
     }   
    } 
    validateEmail(email : string) { 
     var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i; 
     return re.test(email); 
    } 
} 

class Person { 
    public name : string; 
    public surname : string; 
    public email : Email; 
    constructor(name : string, surname : string, email : Email){ 
     this.email = email; 
     this.name = name; 
     this.surname = surname; 
    } 
    greet() { 
     alert("Hi!"); 
    } 
} 

Đảm bảo rằng lớp học có một lần duy nhất sibility làm cho nó theo mặc định cũng dễ dàng hơn để xem những gì nó làm và làm thế nào bạn có thể mở rộng/cải thiện nó.

+3

Vì vậy, bây giờ chúng ta sẽ nhận được rất nhiều lớp methos đơn trong dự án của chúng ta? –

+3

Có, bạn tạo ra các tính năng phức tạp hơn bằng cách sáng tác các thực thể đơn lẻ rất đơn giản. –

2

Nguyên tắc trách nhiệm duy nhất (SRP) quy định rằng một lớp hoặc phương pháp chỉ nên thực hiện một việc và không nên làm bất kỳ điều gì có liên quan. Một lớp nên chỉ có một lý do để thay đổi.

Một ví dụ điển hình có thể một lớp EmailSender:

  • này chỉ nên đối phó với việc gửi một email ra.
  • điều này không chịu trách nhiệm tải nội dung email từ cơ sở dữ liệu hoặc thậm chí định dạng nội dung email được gửi.

Here là một bài viết về điều này.

0

Lớp học chỉ nên có một lý do để thay đổi.

Nguyên tắc này quy định rằng nếu chúng ta có 2 lý do để thay đổi cho một lớp, chúng ta phải chia chức năng thành hai lớp. Mỗi lớp sẽ chỉ xử lý một trách nhiệm và nếu trong tương lai chúng ta cần phải thực hiện một thay đổi, chúng ta sẽ làm cho nó trong lớp xử lý nó.

Nếu có hai lý do khác nhau để thay đổi, có thể hiểu rằng hai nhóm khác nhau có thể làm việc trên cùng một mã vì hai lý do khác nhau. Mỗi người sẽ phải triển khai giải pháp của nó, trong trường hợp của một ngôn ngữ được biên dịch (như C++, C# hoặc Java), có thể dẫn đến các mô-đun không tương thích với các nhóm khác hoặc các phần khác của ứng dụng.

Nguyên tắc này liên quan chặt chẽ đến các khái niệm về khớp nối và gắn kết. Khớp nối đề cập đến cách liên kết chặt chẽ các khía cạnh khác nhau của một ứng dụng, trong khi sự gắn kết đề cập đến mức độ liên quan chặt chẽ đến nội dung của một lớp hoặc gói cụ thể. Tất cả nội dung của một lớp đơn lẻ được kết hợp chặt chẽ với nhau, vì bản thân lớp đó là [đơn vị duy nhất] [1] phải được sử dụng hoàn toàn hoặc hoàn toàn không được sử dụng.

bài viết trên blog của tôi về vấn đề này:

http://javaexplorer03.blogspot.in/2016/12/single-responsibility-principle.html

+0

https://www.youtube.com/watch?v=Gt0M_OHKhQE video này hỗ trợ "Lớp học chỉ nên có một lý do để thay đổi" – code90

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