双向关联,哪个更好?

时间:2017-07-30 22:31:03

标签: design-patterns optimization associations setter

不是真的有问题,但我多次想知道如何在代码中实现双重关联......

我们有一个例子。一辆男子汽车戴着一顶帽子,帽子可以戴在一个男士身上。但如果男人戴帽子,帽子的主人必须是那个男人。

以下是我以前的做法(Java):

字符中:

public void setHat (Hat hat) {
    Hat former = this.hat;
    this.hat = hat;
    if (former != null && former.getOwner() == this)
        former.setOwner(null);
    if (hat != null && hat.getOwner() != this)
        hat.setOwner (this);
}

Hat

public void setOwner (Character c) {
    Character former = this.owner;
    this.owner = c;
    if (former != null && former.getHat() == this)
        former.setHat(null);
    if (c != null && c.getHat() != this)
        c.setHat (this);
}

这样,男人的帽子和帽子的主人总是协调一致。

但是......这对我来说听起来有点笨拙。请问有什么更好的方法来实现这种条件设置器?这对我非常有用。

(如果我犯了错误,那只是因为长棍面包好吗?^^)

UP,请^^

1 个答案:

答案 0 :(得分:1)

一些设计原则适用。 封装意味着你不会让你的任何一个对象(帽子或人)处于不一致的状态。我认为你的解决方案正在实现这一目标。

第二个原则被称为Demeter 法则,其存在是为了通过减少耦合来使维护软件更容易。它声明一个方法应该只使用

  • 其类的实例字段
  • 参数
  • 使用new
  • 构建的对象

目的是让方法避免让另一个对象给它一部分内部状态来处理。由于Hat有一个Man类型的实例字段,反之亦然,它可能不是那么糟糕。

可以应用的设计模式(如果您想要删除冗余代码)可能是Mediator。这是解决方案的一部分(你可以真正使用一个处理管理的类,而不是一直使用Mediator模式):

enter image description here

这方面的缺点是Man.setHatHat.setMan是公共方法,可以被任何人调用,而不必考虑您可以为Mediator编程的“全局”条件。例如,其他一些类可以在几个不同的setHat(h)对象上调用Man

在这种情况下,你可以使用断言(按合同设计)来确保任何调用这些方法的人都不会违反所谓的不变量,例如,Man.setHat(h)的前提条件是h.man == null OR h.man == this(它还没有被另一个人穿着)。但是,我不确定是否会比当前代码做的更少笨拙

最后,您可以在不使用双向关联的情况下应用 KISS 原则。例如,如果Hat必须知道它所在的Man(可能不太可能发生),那么您实现了一个Hat.getMan()方法,该方法遍历已知{{1}列表}对象,搜索自己(或者如果你担心凝聚力,可以使用其他类来为你找到它)。性能是您可能不想这样做的原因。

相关问题:https://softwareengineering.stackexchange.com/questions/200949/class-design-with-bi-directional-relationships