Theo luật của Demeter, một lớp học có được phép trả lại một trong những thành viên của nó không?
Vâng, nó chắc chắn là như vậy.
Hãy nhìn vào những điểm chính :
- Mỗi đơn vị chỉ nên có kiến thức hạn chế về các đơn vị khác: chỉ các đơn vị "chặt chẽ" liên quan đến đơn vị hiện tại.
- Mỗi đơn vị chỉ nên nói chuyện với bạn bè của mình; đừng nói chuyện với người lạ.
- Chỉ nói chuyện với bạn bè ngay lập tức của bạn.
Tất cả ba trong số đó khiến bạn hỏi một câu: Ai là bạn?
Khi quyết định trả lại cái gì, Luật Demeter hoặc nguyên tắc ít kiến thức nhất (LoD) không cho rằng bạn bảo vệ chống lại các lập trình viên khăng khăng vi phạm nó. Nó ra lệnh rằng bạn không buộc các lập trình viên vi phạm nó.
Làm cho những nhầm lẫn này là chính xác lý do tại sao rất nhiều người nghĩ rằng một setter phải luôn luôn trả về khoảng trống. Không. Bạn phải cho phép một cách để thực hiện các truy vấn (getters) không thay đổi trạng thái của hệ thống. Đó là phân tách truy vấn lệnh cơ bản .
Điều này có nghĩa là bạn có thể tự do đi sâu vào một cơ sở mã kết nối bất cứ điều gì bạn muốn? Không. Xâu chuỗi lại với nhau những gì có nghĩa là bị xích lại với nhau. Nếu không, chuỗi có thể thay đổi và đột nhiên công cụ của bạn bị hỏng. Đây là những gì có nghĩa là bạn bè.
Chuỗi dài có thể được thiết kế cho. Các giao diện thông thạo, iDSL, phần lớn Java8 và StringBuilder cũ đều có nghĩa là cho phép bạn xây dựng chuỗi dài. Họ không vi phạm LoD vì mọi thứ trong chuỗi đều có nghĩa là làm việc cùng nhau và hứa sẽ tiếp tục làm việc cùng nhau. Bạn vi phạm demeter khi bạn xâu chuỗi những thứ không bao giờ nghe thấy về nhau. Bạn bè là những người hứa sẽ giữ cho chuỗi của bạn hoạt động. Bạn bè của bạn bè đã không.
Ngoài các lớp được chỉ định cụ thể để trả về các đối tượng - chẳng hạn như các lớp của nhà máy và nhà xây dựng - thì phương thức trả lại một đối tượng là gì, ví dụ như một đối tượng được giữ bởi một trong các thuộc tính của lớp hoặc sẽ vi phạm luật của demeter (1) ?
Điều này chỉ tạo ra một cơ hội để vi phạm demeter. Đây không phải là một vi phạm. Điều này thậm chí không hẳn là xấu.
Và nếu nó vi phạm luật demeter, liệu đối tượng được trả về có phải là một đối tượng bất biến đại diện cho một phần dữ liệu và không chứa gì ngoài getters cho dữ liệu này (2) không?
Bất biến là tốt nhưng không liên quan ở đây. Bắt mọi thứ thông qua một chuỗi dài hơn không làm cho nó tốt hơn. Điều gì làm cho nó tốt hơn là tách biệt việc nhận được từ việc sử dụng. Nếu bạn đang sử dụng, hãy hỏi những gì bạn cần làm tham số. Đừng đi săn lùng nó bằng cách đào sâu vào những kẻ lạ mặt.
Trong mã giả:
Tôi nghi ngờ rằng luật của Demeter cấm một mô hình như ở trên. Tôi có thể làm gì để đảm bảo rằng doS SomethingElse () có thể được gọi trong khi không vi phạm luật (3)?
Trước khi tôi nói về hãy x.doSomethingElse(a)
hiểu rằng bạn đã viết một cách cơ bản
b.getA().doSomething()
Bây giờ, LoD không phải là một bài tập đếm số chấm . Nhưng khi bạn tạo một chuỗi bạn đang nói rằng bạn biết cách lấy một A
(bằng cách sử dụng B
) và bạn biết cách sử dụng một chuỗi A
. Bây giờ A
và B
tốt hơn là bạn thân vì bạn chỉ cần ghép chúng lại với nhau.
Nếu bạn vừa yêu cầu một cái gì đó để tay bạn một A
như điều bạn có thể sử dụng A
và sẽ không chăm sóc nó đến từ đâu và B
có thể sống một cuộc sống hạnh phúc và tự do của nỗi ám ảnh của bạn với nhận được A
từ B
.
Vì x.doSomethingElse(a)
không có thông tin chi tiết về x
nguồn gốc từ đâu, LoD không có gì để nói về nó.
LoD có thể khuyến khích tách sử dụng khỏi xây dựng . Nhưng tôi sẽ chỉ ra rằng nếu bạn tôn trọng mọi đối tượng là không thân thiện, bạn sẽ bị kẹt viết mã trong các phương thức tĩnh. Bạn có thể xây dựng một biểu đồ đối tượng phức tạp tuyệt vời theo cách này nhưng cuối cùng bạn phải gọi một phương thức trên nó để bắt đầu mọi thứ hoạt động. Bạn chỉ cần quyết định bạn bè của bạn là ai. Không thể tránh khỏi điều đó.
Vì vậy, có, một lớp được phép trả lại một trong những thành viên của nó theo LoD. Khi bạn làm, bạn nên làm rõ nếu thành viên đó thân thiện với lớp của bạn bởi vì nếu không, một số khách hàng có thể thử ghép bạn với lớp đó bằng cách sử dụng bạn để có được nó trước khi sử dụng nó. Điều đó quan trọng bởi vì bây giờ những gì bạn trả lại phải luôn hỗ trợ việc sử dụng đó.
Có nhiều trường hợp điều này chỉ đơn giản là không phải là một mối quan tâm. Bộ sưu tập có thể bỏ qua điều này đơn giản vì chúng có nghĩa là bạn bè với mọi thứ sử dụng chúng. Đối tượng giá trị tương tự là thân thiện với tất cả mọi người. Nhưng nếu bạn đã viết một tiện ích xác thực địa chỉ yêu cầu một đối tượng nhân viên mà nó trích xuất một địa chỉ từ đó, thì chỉ cần hỏi địa chỉ, bạn sẽ hy vọng rằng cả nhân viên và địa chỉ đều đến từ cùng một thư viện.