C++ 试图理解德米特定律,因为它适用于我的代码
我有一个简单的C++ 试图理解德米特定律,因为它适用于我的代码,c++,oop,law-of-demeter,C++,Oop,Law Of Demeter,我有一个简单的存储类,它包含一个库存。库存包含项目的列表。为了修改库存中的一个项目,我必须写: Store store( /*parameters*/ ); store.accessInventory(/*password*/).accessItem(/*item name*/).setPrice(9.50); 据我所知,这打破了传统,因为存储必须通过库存进入项目,才能调用setPrice() 我想将这一违法行为与纸童和客户的经典案例中的违法行为进行协调。在paper boy的例子中,pape
存储
类,它包含一个库存
。库存
包含项目的列表。为了修改库存
中的一个项目
,我必须写:
Store store( /*parameters*/ );
store.accessInventory(/*password*/).accessItem(/*item name*/).setPrice(9.50);
据我所知,这打破了传统,因为存储
必须通过库存
进入项目
,才能调用setPrice()
我想将这一违法行为与纸童和客户的经典案例中的违法行为进行协调。在paper boy的例子中,paper boy“知道”客户太多,假设他将使用钱包付款。如果客户的付款方式改变,报童也必须改变
在我的代码中,有哪些假设会导致像paper boy示例中遇到的问题
我明白法律实际上更像是一个指导方针,在这种情况下遵守法律可能不是最好的主意,但我想在继续之前至少了解法律。谢谢。您的代码假设库存对象是唯一一个在价格发生变化时需要通知的对象
想象一下,除了包含物品清单之外,你的商店的橱窗里还挂着一些广告海报
如果您遵循德米特定律,您的存储对象可能有一个很好的方法,如下所示:
void Store :: SetItemPrice(string item_name, float item_price)
{
inventory.SetItemPrice(item_name, item_price);
for (int i=0; i<num_advertising_posters; i++)
{
// Update any posters with the new price!
if (advertising_posters[i].advertised_item == item_name)
{
advertising_posters[i].SetAdvertisedPrice(item_price);
}
}
}
void Store::SetItemPrice(字符串项目名称,浮动项目价格)
{
存货。设置项目价格(项目名称、项目价格);
对于(int i=0;i您的示例非常接近paperboy示例。您的代码依赖于具有方法setPrice(float)的当前项接口。如果更改该接口,则需要更新
store.accessInventory(password).accessItem(name).setPrice(price)
无论它发生在哪里
更好的解决方案是为表单的存储和库存创建函数
void Store::setItemPrice(string password, string name, float price)
{
accessInventory(password).setItemPrice(name, price);
}
无效库存::setItemPrice(字符串名称,浮动价格)
{
accessItem(名称).setPrice(价格);
}
通过这种方式,您可以在代码的其余部分使用这些函数,并在项目或库存接口发生更改时相应地更改它们
在我的代码中,有哪些假设会导致像paper boy示例中遇到的问题
愤怒的顾客,愤怒的员工,愤怒的经理,愤怒的会计
顾客们并不介意当所列价格高于他们所收取的价格时感到惊讶,但当所收取的价格高于他们预期的价格时,他们肯定会受到惩罚。工蜂们不喜欢愤怒的顾客向他们走来,因为愚蠢的新手店经理没有遵守协议,改变了价格直接在库存中。低层和中层经理也不喜欢这样,因为他们受到来自各方的悲伤。豆子柜台也喜欢在豆子价值突然变化时得到通知
杰里米在回答中提到的不仅仅是广告海报。需要告诉一些人更改一堆物品旁边标明价格的小价格标签。需要派遣一组人员携带便携式打印机更改该类型物品上的价格标签。这些人需要安排时间,而杰里米你最好不要在没有和部门经理谈的情况下这样做。等等。通过库存来改变价格是个坏主意
顺便说一句,所有这些都来自于一个人,他认为Demeter法则更适合称为偶尔有用的Demeter建议。但这似乎不是该法则的中心目的。根据这一点,该法则的中心目的似乎更多的是掩盖调用方法和目的之间的特定路径nation方法,以便在路径发生更改时调用方法不会受到影响。向SetItemPrice()添加附加功能的功能这似乎是法律的一个很好的副作用,但不是中心目的。@JamesGold我认为我们从稍微不同的方向走到了同一点。在我的例子中,商店对象外的代码可以保持不变,尽管引入了广告功能。这是屏蔽特定路径的好处。我不知道ee当引入广告功能时,屏蔽特定路径与不必在Store对象外更改代码有多大关系。@JamesGold:为预测未来代码更改而证明LoD是过早优化的一种情况。Jeremy的广告示例是更好的法律证明。item\u name
should是按价值传递的。这同样适用于库存,而不仅仅是存储。这仍然是违反法律的。谢谢你发布这篇文章。我已经相应地编辑了这篇文章。