面向对象编程:如何处理具有相互关系的对象?

7
假设有两个通过某些关系相关的类。例如,一个 Student 维护他所选修的Class列表,每个Class都有一个学生名单。我不希望让 Student 直接能够修改其 Class 列表,因为每次修改都需要进行类似于修改 ClassStudent 名单的操作,反之亦然。
一个解决方案是创建一个唯一目的是跟踪 Class-Student 关系的类,比如说 Registrar。但是如果 Student 中的某个方法需要知道它的 Class 列表,那么就需要将 Registrar 传递给 Student。这似乎不太好。看起来 Student 不应该访问 Registrar,因为在那里它也可以访问其他Student。我可以想到一种解决方案,创建一个类作为 StudentRegistrar 之间的中介者,只向 Student 显示它需要知道的内容,但这可能有点过头了。另一个解决方案是从 Student 中删除任何需要访问其类的方法,将其放在 Registrar 或其他可以访问 Registrar 的类中。
我问这个问题是因为我在编写Java版的棋盘游戏。我正在思考棋子与棋格以及棋子与玩家之间的关系。如果在上面的例子中,让 Student 访问 Registrar 是不允许的,那么像 Piece 这样的类是否可以访问棋盘 Board,因为 Piece 需要查看周围信息以决定移动是否有效?
在这种情况下,标准做法是什么?
2个回答

2
如果关系可以改变 - 类应该尽可能解耦,因此每个类都应创建一个接口,不要在类之间引入紧密的关系。您可以使用中间服务/帮助程序来实现高度分离,这些服务/帮助程序封装了类之间通信的逻辑,因此在这种情况下,即使两个类都通过接口进行抽象,也不应将一个类注入到另一个类中。基本上,Student 不知道任何关于 Class 的事情,而 Class 也不知道任何关于 Student 的事情。我不确定这种复杂性是否在您的情况下有意义,但无论如何,您都可以实现它。
这里您可能会发现一个有用的中介者设计模式,它可以封装两个解耦实体之间的交互逻辑,请查看一下。
引用:
使用中介者模式,对象之间的通信被封装在一个中介者对象中。对象不再直接相互通信,而是通过中介者进行通信。这降低了通信对象之间的依赖关系,从而降低了耦合度。

1
我认为你在你的很好的例子和解释中发现的是,面向对象并不能很好地解决所有问题。只要责任被明确地界定和分配,一切都很好。只要每个责任都恰好适合一个桶(即类),设计就相当容易。但是这里存在一个权衡:
  • 如果我为每个责任定义一个单独的类,我将得到一个臃肿的设计,很难理解(有时也很难维护)。
  • 如果我为每个单独的责任包含至少一个接口,我将得到比我需要的更多的类和接口。
  • 如果我决定其中一个类也负责关系,那么这个对象对另一个对象的了解就会比平常多。
  • 如果你在每种情况下引入一个中介或类似的东西,你的设计将比问题更加复杂。

因此,也许你应该问以下问题:

  • 两个对象之间的关系改变的可能性有多大?
  • 关系是否存在于每个端点的多种类型的对象之间?
  • 该系统的这部分是否是高度可见的部分,以便许多其他部分将与其接口(因此将依赖于它)?
采用最简单的解决方案并从那里开始。只要保持解决方案简单,它只是你的代码(你不为他人设计库),就有可能稍后更改设计而无需麻烦。
所以在你的具体情况下,
1. 棋盘字段应该可以访问整个棋盘XOR 2. 场上的棋子应该负责移动XOR 3. 应该有一个对象类型(ChessGame?)负责整体关于移动、阻挡、攻击等的知识
我认为所有这些都是有效的,取决于你特定的“业务案例”,哪一个是最有效的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接