得墨忒耳和飞机的法则

时间:2016-06-20 06:52:16

标签: c++ law-of-demeter

这个游戏的源代码是开源的,所以我决定查看它。在其中,我找到了类似的东西:

// This ActionManager is basically a controller like in the MVC pattern.
void ActionManager::HandleQueryMessage(csString xml, Client* client)
{
    //check the two hands as a start.
    psItem* item = client->GetCharacterData()->Inventory().GetInventoryItem(PSCHARACTER_SLOT_RIGHTHAND);
    if(!item || !item->GetItemCommand().Length())
        item = client->GetCharacterData()->Inventory().GetInventoryItem(PSCHARACTER_SLOT_LEFTHAND);
}

获得该项目的第一行显然违反了德米特定律。但是,即使它被更改为client->GetCharacterData()->GetInventoryItem(PSCHARACTER_SLOT_RIGHTHAND);,它仍然会违反得墨忒耳定律(据我所知)。

可以做些什么呢?或者这是LOD不适用的地方之一[如我的第二个例子]?

GetInventoryItem提升到client类在我看来没有意义,因为客户端与character无关。

client类中为所有xx方法创建包装器character类似乎有点过分。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

正如你自己建议的那样,如果你想完全关注LOD,你需要像...这样的功能。

Item* Client::GetCharacterInventoryItem(int itemID) 
{
    return characterData->getInventoryItem(itemId);
}
/* ... */
Item* CharacterData::getInventoryItem(int itemID)
{
    return inventory->getItem(itemId)
}
/* ... */ 
Item* Inventory::getItem(int itemID)
{
    assert_valid_itemID(itemID);
    return inventory_table[itemId];
}

这个额外的间接值得吗?我不知道,这取决于案例,您的个人偏好等。正如评论所示,LOD应被视为一个指导方针,而不是真正的法律。另一方面,根据我的个人经验,经常打破它,你会遇到麻烦...... :)