我在理解如何允许对象相互了解方面遇到了问题。
在我的简单示例中,我有类:Bill
、Customer
、Checkout
和 Cart
。客户有他们的账单
列表,购物车与customer
关联,结帐完成购买操作(将bill
添加到customer
)
SO 在方法 public void checkouts(Cart cart)
中,我初始化新账单 Bill bill = new Bill(cart)
然后我想向客户添加账单。我有 3 种可能的方法:
cart.getCustomer().getBills().add(bill);
// ^^^ directly add bill to ArrayList in Customer
cart.getCustomer().addBill(bill);
// ^^^ Customer get bill and put it itself in their own method
cart.addBillToCustomer(bill);
// ^^^ In this example class Checkout doesn't now anything about customer.
// Responsibility goes to cart which calls getCustomer().addBill(bill)
我猜第一个真的是错误的,因为 Checkout
必须知道 getBills()
返回 array list
(这是危险的)
在第二个示例中,类 checkouts
获取与它没有直接关联的客户,并且它必须知道客户界面才能添加账单。
在第三个结账示例中,它与客户没有直接关联,不使用任何关于客户的知识,它只是将任务委托(delegate)给直接连接到客户
的cart
> (它有字段 Customer 客户)
哪种解决方案最好,为什么以及为什么其他解决方案更差?
最佳答案
选项 1:cart.getCustomer().getBills().add(bill);
这样做的主要问题是您依赖于 getBills()
返回集合的可变性。这是一个坏主意,因为它破坏了封装,这就是为什么通常在 getter 中返回内部集合的不可变副本/ View 。到那时,这个解决方案根本行不通。
选项 2:cart.getCustomer().addBill(bill);
这假设知道购物车将有一个与之关联的客户,并且客户可以向他们添加账单。这些假设没有错,但还有第三个隐含的假设:Cart
不需要知道客户何时收到新账单。事实上,Cart
甚至不必存在。
选项 3:cart.addBillToCustomer(bill);
从上面继续,第三次调用的语义非常不同。此调用的意思是:客户
只能通过购物车
计费。
结论
总而言之:选项 1 是完全错误的,但您选择选项 2 还是选项 3 取决于您希望模型表达的内容,它们代表了业务逻辑之间的实际差异。
关于java - 对象对其他对象了解多少?是违反得墨忒耳定律的例子吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29277105/