Tôi đang đọc một cuốn sách tên là Rails AntiPotypes và họ nói về việc sử dụng ủy quyền để tránh vi phạm Luật Demeter. Đây là ví dụ điển hình của họ:
Họ tin rằng việc gọi một cái gì đó như thế này trong bộ điều khiển là xấu (và tôi đồng ý)
@street = @invoice.customer.address.street
Giải pháp đề xuất của họ là làm như sau:
class Customer
has_one :address
belongs_to :invoice
def street
address.street
end
end
class Invoice
has_one :customer
def customer_street
customer.street
end
end
@street = @invoice.customer_street
Họ nói rằng vì bạn chỉ sử dụng một dấu chấm, nên bạn không vi phạm Luật Demeter ở đây. Tôi nghĩ rằng điều này là không chính xác, bởi vì bạn vẫn đang thông qua khách hàng để đi qua địa chỉ để lấy đường phố của hóa đơn. Tôi chủ yếu có ý tưởng này từ một bài đăng trên blog mà tôi đọc:
http://www.dan-manges.com/blog/37
Trong bài viết trên blog, ví dụ điển hình là
class Wallet
attr_accessor :cash
end
class Customer
has_one :wallet
# attribute delegation
def cash
@wallet.cash
end
end
class Paperboy
def collect_money(customer, due_amount)
if customer.cash < due_ammount
raise InsufficientFundsError
else
customer.cash -= due_amount
@collected_amount += due_amount
end
end
end
Bài đăng trên blog nói rằng mặc dù chỉ có một dấu chấm customer.cash
thay vì customer.wallet.cash
, mã này vẫn vi phạm Luật Demeter.
Bây giờ trong phương thức Paperboy coll_money, chúng tôi không có hai dấu chấm, chúng tôi chỉ có một dấu chấm trong "customer.cash". Đoàn này đã giải quyết vấn đề của chúng tôi? Không có gì. Nếu chúng ta xem xét hành vi, một người bán báo vẫn tiếp cận trực tiếp vào ví của khách hàng để rút tiền.
BIÊN TẬP
Tôi hoàn toàn hiểu và đồng ý rằng đây vẫn là một vi phạm và tôi cần tạo một phương thức Wallet
gọi là rút tiền xử lý khoản thanh toán cho tôi và tôi nên gọi phương thức đó trong Customer
lớp. Những gì tôi không nhận được là theo quy trình này, ví dụ đầu tiên của tôi vẫn vi phạm Luật Demeter vì Invoice
vẫn tiếp cận trực tiếp Customer
để đi ra đường.
Ai đó có thể giúp tôi xóa sự nhầm lẫn. Tôi đã tìm kiếm trong 2 ngày qua để cố gắng để chủ đề này chìm vào, nhưng nó vẫn còn khó hiểu.