试图理解得墨忒耳定律,因为它适用于我的代码

Trying to understand the Law of Demeter as it applies to my code

本文关键字:因为 适用于 代码 我的 定律      更新时间:2023-10-16

我有一个简单的Store类,其中包含一个InventoryInventory包含Item的列表。为了修改Inventory中的Item之一,我必须编写:

Store store( /*parameters*/ );
store.accessInventory(/*password*/).accessItem(/*item name*/).setPrice(9.50);

据我了解,这违反了得墨忒耳定律,因为Store必须通过Inventory进入Item才能召唤setPrice()

我想将这种违法行为与经典例子中的违法行为与纸男孩和客户之间的违法行为相协调。在纸男孩的例子中,纸男孩"了解"了太多关于客户的信息,假设他会用钱包付款。如果客户的付款方式发生变化,纸男孩也必须改变。

在我的代码中做出了哪些假设,可能会导致像纸男孩示例中遇到的问题?

我知道法律实际上更像是一个指导方针,在这种情况下遵守它可能不是最好的主意,但我想在继续之前至少了解法律。谢谢。

您的代码假定 Inventory 对象是唯一需要在价格更改时通知的对象。

想象一下,除了包含商品清单外,您的商店还在其橱窗中挂了一些广告海报。

如果您遵循得墨忒耳定律,您的 Store 对象可能有一个不错的方法,如下所示:

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);
      }
   }
}

。但是,如果您允许调用代码直接访问库存对象,那么就没有简单/万无一失的方法来确保每当价格更新时广告始终得到更新,因此在某些时候,您商店的广告海报可能会显示产品的旧/错误价格。 得墨忒耳定律使避免这种错误变得更加容易。

在我的代码中做出了哪些假设,可能会导致像纸男孩示例中遇到的问题?

愤怒的客户。愤怒的工作人员。愤怒的经理。愤怒的会计师。

当列出的价格高于他们收取的价格时,

客户不介意感到惊讶,但是当他们被收取的价格高于他们预期的价格时,他们肯定会被POed。工蜂不喜欢愤怒的顾客来找他们,因为愚蠢的新手商店经理不遵守协议并直接在库存中更改价格。中低层管理者也不喜欢这样,因为他们会从四面八方感到悲伤。豆类计数器也喜欢在豆子的价值突然变化时得到通知。

这不仅仅是杰里米在回答中提到的广告海报。需要告诉某人更改指定价格的物品堆旁边的小定价标签。需要派遣一群人携带便携式打印机来更改该类型每件商品上印有的价格。这些人需要安排,你最好不要在没有与部门经理交谈的情况下这样做。等等等等。通过库存来改变价格是一个坏主意。

顺便说一句,以上所有内容都来自一个认为得墨忒耳定律最好称为得墨忒耳偶尔有用的建议的人。

您的示例非常接近 paperboy 示例。您的代码依赖于具有 setPrice(float) 方法的当前 Item 接口。如果更改该接口,则需要更新

store.accessInventory(password).accessItem(name).setPrice(price)

它发生的任何地方。

更好的解决方案是为表单的商店和库存创建函数

void Store::setItemPrice(string password, string name, float price)
{
  accessInventory(password).setItemPrice(name, price);
}
无效库存:

:设置项目价格(字符串名称,浮动价格)

{ accessItem(name).setPrice(price);
}

这样,您可以在代码的其余部分使用这些函数,并在物品或物品栏接口发生更改时相应地更改它们。