最近我一直在努力解决一些我不知道如何优雅解决的经常性设计问题。
假设我正在与几个玩家进行游戏,并为每个玩家制作一些连接件。这些部分一起形成半复杂的集合或结构。现在我可以用两种方式实现这个结构:通过各自的指针隐式存储结构,即:
class BigPiece extends Piece {
Piece opposingPiece, nextPiece, previousPiece, index;
}
或者我可以在集合类中实现此结构并保持信息集中:
class SomeCollection<Collection<Piece>> {
SomeOtherCollection<Collection<Piece>> collection
= new SomeOtherCollection<Collection<Piece>>();
public SomeCollection() {
collection.add(new PieceCollection<Piece>();
collection.add(new PieceCollection<Piece>();
collection.add(new PieceCollection<Piece>();
}
public Piece getPiece(int playerIndex, int pieceIndex) {
collection.get(playerIndex).get(pieceIndex);
}
public Piece getOpposingPiece(int playerIndex, int pieceIndex) {
int nextPlayerIndex = collection.listIterator(playerIndex).nextIndex();
return this.collection.get(nextPlayerIndex).get(pieceIndex);
}
}
现在我通常偏爱第二个,但这只是基于我的胆量,我在课堂设计方面没有那么多经验,特别是在大型应用程序方面。我可以看到双方的利弊。
我通常在第一个解决方案中遇到的问题是,您仍然需要在某些构建器或工厂中创建实际将对象链接在一起的关联。这对我来说似乎不太健壮。谁可以向我保证所有指针在整个应用程序的生命周期中都是正确的?
第二种解决方案更多地集中了数据。虽然这对于高级班级来说真的很愚蠢(比如个人作品)。我通常遇到的问题是,无论何时我想遍历这个集合,我都必须在较低的层次上进行。你不能问一块'嘿,你的对手是什么?'不,你必须得到一个游戏对象来获得指向你的收藏的指针,然后你会问对方的作品是什么。这使得更多“管理”类从应用程序周围收集数据(方法链=()以最终实现您的算法。这似乎违反了Law of Demeter。
当然我也可以从每个单独的部分添加指向相应集合的指针,但我不知道这是否是一个好主意,因为这似乎只是重复的信息。
答案 0 :(得分:0)
我的个人建议更多是第二种选择,而不是第一种选择。正如你所指出的那样,一件作品不应该(至少在这种情况下)知道它的对立/下一首/上一首作品是什么。
管理器类更符合逻辑,更好地促进类之间的通信,而不是引用其他部分的部分。我承认我并不完全了解得墨忒耳定律,但是Wikipedia让我相信它完全是关于封装的,经理类实际上也会有所帮助!
我不认为Pieces(再次,在这种情况下)应该能够,例如,移动另一件。但是,经理类逻辑上想要。
这是我的建议,我希望它有所帮助!