【问题标题】:law of demeter and planeshift得墨忒耳法则和移位法则
【发布时间】:2016-06-20 06:52:16
【问题描述】:

这个游戏的源代码是开源的,所以我决定去看看。在其中,我发现了类似的内容:

// 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 类中为 character 类的所有 xx 方法创建包装器似乎有点过头了。

有什么想法吗?

【问题讨论】:

  • “得墨忒耳法则”实际上是“得墨忒耳的指南”。这个问题对于 Stack Overflow 来说有点太主观了,因为这是一个编码风格的问题,人们更喜欢如何设计某些功能。如果您想查看高质量的开源游戏代码库,请尝试 Doom 3:fabiensanglard.net/doom3
  • @DietrichEpp planeshift 源是服务器端的。厄运只是客户端。
  • 这是不正确的。 《毁灭战士 3》的来源不仅仅是客户端。
  • @DietrichEpp 那么毁灭战士3游戏服务器的项目在哪里?我找不到它。
  • 这真的取决于!您可能会注意到投票赞成关闭的问题“过于宽泛”和“主要基于意见”,请尝试具体化。如果类的名称是 LeftOrRightCharacterHolder,则答案是将 client->GetCharacterData()->Inventory() 移出方法。

标签: c++ law-of-demeter


【解决方案1】:

正如你自己建议的那样,如果你想完全遵循 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];
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 2012-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多