从设计角度“泄漏这个”

时间:2011-11-22 22:21:25

标签: java constructor logic this

  

警告:在构造函数中泄漏“this”

我一直在努力,我有一种唠叨的感觉,因为我的设计是错误的或不是最佳的。

据我所知,这个警告引起了我的注意,即我允许访问可能未完全初始化的对象。

假设我需要一个具有HAS且需要List(Frame(列表列表))的Frame。在List中,我可能想要做一些事情,比如add()。为了确保Frame尽可能少地了解List(只有它有一个),我想从列表中访问包含的Frame(List HAS a Frame?)。这看起来有点傻,但我有2个以上的List实现,它们将以不同的方式使用Frame ..

为了确保正确使用我的代码,我需要在List的构造函数中使用Frame。 我还需要在Frame的构造函数中使用List,因为它必须有一个:

public abstract class Frame {
    private final List list;

    public Frame(List list) {
        this.list = list;
        list.setFrame(this);
    }
}

public abstract class List {
    private Frame frame;

    protected final void setFrame(Frame frame) {
        this.frame = frame;
    }
}

那么,这是一个糟糕的设计,还是我真的应该创建一些中间脚手架,甚至将脚手架留给用户?

谢谢!

2 个答案:

答案 0 :(得分:5)

介绍工厂方法:

public static Frame createFrame(List list) {
    Frame frame = new Frame(list);
    list.setFrame(frame);
}

private Frame(List list) {
    this.list = list;
}

这不会泄露这一点,并且始终确保一切都正确配置,而不需要每个调用者都记住初始化关联的两面。

答案 1 :(得分:1)

我认为这种“双重链接”结构,其中一个框架指向一个指向其父框架的List,这是你应该避免的,除非你有特殊的需要。如果可能的话,你应该尝试将两个对象中的一个作为指向“孩子”的“父母”。

起初有点难以理解为什么双链接不是一个好主意,但这里有一些原因:

  1. 在具有明确父子关系的结构中,在多个父级中重用相同的子对象是微不足道的。另一方面,在双链结构中,如果要创建一个与原始元素共享某些元素的新结构,则必须创建感兴趣元素的新副本,否则必须销毁原始元素结构
  2. 有很多设计模式依赖于对象图中明确的“命令”链,而双链结构模糊了代码读者的命令链。
  3. 通过将父级作为“上下文”参数传递给处理子级的方法,可以更好地处理很多处理子级需要知道子级出现的父级的情况。这种模式的典型例子是解释器,其中表达式的评估将“环境”作为参数,该“环境”包含评估子表达式所需的所有外部信息。 (或者,您可以使用有状态迭代器或分层访问者来导航结构并跟踪位置。)
  4. 这并不是说双链结构永远不合适,而是简单的单链结构应该是第一选择。