2016-06-20 7 views
1

Der Quellcode dieses Spiels ist Open Source, also entschied ich mich, es auszuprobieren. Darin fand ich etwas wie:Gesetz von Demeter und Planeshift

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

Die erste Zeile, um den Artikel zu erhalten, verstößt eindeutig gegen das Gesetz von Demeter. Aber selbst wenn es in client->GetCharacterData()->GetInventoryItem(PSCHARACTER_SLOT_RIGHTHAND); geändert würde, würde es immer noch das Demeter-Gesetz verletzen (soweit ich weiß).

Was kann dagegen getan werden? oder ist das einer der Orte, wo LOD nicht gilt [wie in meinem zweiten Beispiel]?

Das Verschieben der GetInventoryItem Klasse client macht aus meiner Sicht keinen Sinn, da der Client nichts mit der character zu tun hat.

Erstellen von Wrappern in der client Klasse für alle xx-Methoden scheint die character Klasse zu übertreiben.

Irgendwelche Gedanken?

+1

Das "Gesetz von Demeter" ist wirklich eine "Richtlinie von Demeter". Diese Frage ist für Stack Overflow ein bisschen zu subjektiv, weil es eine Frage des Codierungsstils ist, wie die Leute ein Feature entwerfen möchten. Wenn Sie eine qualitativ hochwertige Open-Source-Spielcodebasis überprüfen möchten, versuchen Sie Doom 3: http://fabiensanglard.net/doom3/ –

+0

@DietrichEpp Die Planeshift-Quelle ist serverseitig tho. Das Doom ist nur Client. – James

+0

Das ist falsch. Die Doom 3-Quelle ist nicht nur Client. –

Antwort

0

Wie Sie selbst vorschlagen, wenn Sie LOD wollen vollständig folgen, Sie möchten, dass Funktionen benötigen ...

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

Ist das zusätzliche Indirektion wert? Ich weiß nicht, das kommt auf den Fall an, auf Ihre persönlichen Vorlieben usw. Wie die Kommentare zeigen, sollte die LOD als Richtlinie betrachtet werden, nicht als Gesetz. Auf der anderen Seite, in meiner persönlichen Erfahrung, brechen Sie es häufig und Sie werden in Schwierigkeiten geraten ... :)

Verwandte Themen