Trách nhiệm duy nhất có thể không phải là điều mà một chức năng duy nhất có thể thực hiện.
class Location {
public int getX() {
return x;
}
public int getY() {
return y;
}
}
Lớp này có thể phá vỡ nguyên tắc trách nhiệm duy nhất. Không phải vì nó có hai chức năng, nhưng nếu mã cho getX()
và getY()
phải đáp ứng các bên liên quan khác nhau có thể yêu cầu thay đổi. Nếu Phó Chủ tịch, ông X gửi một bản ghi nhớ rằng tất cả các số sẽ được biểu thị dưới dạng số dấu phẩy động và Giám đốc Kế toán, bà Y khẳng định rằng tất cả các số mà bộ phận của bà đánh giá sẽ vẫn là số nguyên cho dù ông X nghĩ gì tốt hơn thì lớp này có tốt hơn một ý tưởng duy nhất về trách nhiệm của ai vì mọi thứ sắp trở nên khó hiểu.
Nếu SRP đã được theo dõi thì sẽ rõ ràng nếu lớp Location đóng góp vào những thứ mà ông X và nhóm của ông được tiếp xúc. Làm rõ những gì lớp chịu trách nhiệm và bạn biết chỉ thị nào tác động đến lớp này. Nếu cả hai đều tác động đến lớp này thì nó được thiết kế kém để giảm thiểu tác động của thay đổi. "Một lớp chỉ nên có một lý do để thay đổi" không có nghĩa là toàn bộ lớp chỉ có thể làm một việc nhỏ. Điều đó có nghĩa là tôi không nên nhìn vào lớp học và nói rằng cả ông X và bà Y đều có hứng thú với lớp học này.
Khác với những thứ như thế. Không, nhiều phương pháp đều ổn. Chỉ cần đặt tên cho nó để làm rõ phương thức nào thuộc về lớp và phương thức nào không.
SRP của chú Bob thiên về Luật của Conway hơn là Luật của Quăn . Chú Bob ủng hộ việc áp dụng Luật xoăn (làm một việc) cho các chức năng chứ không phải các lớp học. SRP cảnh báo chống lại lý do trộn để thay đổi cùng nhau. Luật của Conway cho biết hệ thống sẽ tuân theo cách thông tin của một tổ chức. Điều đó dẫn đến việc theo dõi SRP vì bạn không quan tâm đến những gì bạn chưa bao giờ nghe về.
"Một mô-đun phải chịu trách nhiệm với một, và chỉ một, diễn viên"
Robert C Martin - Kiến trúc sạch
Mọi người cứ muốn SRP về mọi lý do để giới hạn phạm vi. Có nhiều lý do để giới hạn phạm vi hơn SRP. Tôi tiếp tục giới hạn phạm vi bằng cách khẳng định lớp học là một sự trừu tượng có thể lấy một cái tên đảm bảo nhìn vào bên trong sẽ không làm bạn ngạc nhiên .
Bạn có thể áp dụng Luật xoăn cho các lớp học. Bạn đang ở ngoài những gì chú Bob nói nhưng bạn có thể làm được. Bạn sai ở đâu là khi bạn bắt đầu nghĩ rằng điều đó có nghĩa là một chức năng. Điều đó giống như nghĩ rằng một gia đình chỉ nên có một đứa con. Có nhiều hơn một đứa trẻ không ngăn cản nó trở thành một gia đình.
Nếu bạn áp dụng luật của xoăn cho một lớp, mọi thứ trong lớp sẽ là về một ý tưởng thống nhất duy nhất. Ý tưởng đó có thể rộng. Ý tưởng có thể là sự kiên trì. Nếu một số chức năng tiện ích ghi nhật ký nằm trong đó, thì chúng rõ ràng không đúng chỗ. Không thành vấn đề nếu ông X là người duy nhất quan tâm đến mã này.
Nguyên tắc cổ điển để áp dụng ở đây được gọi là Tách mối quan tâm . Nếu bạn tách tất cả các mối quan tâm của mình, có thể lập luận rằng những gì còn lại ở bất kỳ nơi nào là một mối quan tâm. Đó là những gì chúng tôi gọi là ý tưởng này trước khi bộ phim City Slickers năm 1991 giới thiệu cho chúng tôi nhân vật Quăn.
Điều này là tốt Chỉ là những gì chú Bob gọi là trách nhiệm không phải là vấn đề đáng lo ngại. Trách nhiệm với anh ấy không phải là thứ bạn tập trung vào. Đó là thứ có thể buộc bạn phải thay đổi. Bạn có thể tập trung vào một mối quan tâm và vẫn tạo mã chịu trách nhiệm cho các nhóm người khác nhau với các chương trình nghị sự khác nhau.
Có lẽ bạn không quan tâm đến điều đó. Khỏe. Nghĩ rằng việc nắm giữ để "làm một việc" sẽ giải quyết tất cả các tai ương trong thiết kế của bạn cho thấy sự thiếu trí tưởng tượng về "một điều" cuối cùng có thể là gì. Một lý do khác để giới hạn phạm vi là tổ chức. Bạn có thể lồng nhiều "một thứ" bên trong "một thứ" khác cho đến khi bạn có một ngăn kéo rác đầy đủ mọi thứ. Tôi đã nói về điều đó trước đây
Tất nhiên, lý do OOP cổ điển để giới hạn phạm vi là lớp có các trường riêng trong đó và sau đó sử dụng getters để chia sẻ dữ liệu đó, chúng tôi đặt mọi phương thức cần dữ liệu đó trong lớp nơi chúng có thể sử dụng dữ liệu ở chế độ riêng tư. Nhiều người thấy điều này quá hạn chế để sử dụng như một bộ giới hạn phạm vi bởi vì không phải mọi phương thức thuộc về nhau đều sử dụng chính xác các trường giống nhau. Tôi muốn đảm bảo rằng bất kỳ ý tưởng nào mang dữ liệu lại với nhau đều là cùng một ý tưởng mang các phương thức lại với nhau.
Cách chức năng để xem xét điều này là a.f(x)
và a.g(x)
chỉ đơn giản là f a (x) và g a (x). Không phải hai chức năng mà là sự liên tục của các cặp chức năng khác nhau. Các a
thậm chí không cần phải có dữ liệu trong đó. Nó có thể chỉ đơn giản là cách bạn biết cái nào f
và cách g
triển khai bạn sẽ sử dụng. Các chức năng thay đổi cùng thuộc về nhau. Đó là đa hình cũ tốt.
SRP chỉ là một trong nhiều lý do để giới hạn phạm vi. Đó là một thứ tốt. Nhưng không phải chỉ có một.