弱要求:如何确保对象初始化

时间:2014-04-07 07:38:52

标签: java spring-bean

我想编写适合bean的类。我观察到一种趋势(主要是使用bean)将所需参数从构造函数移动到setter(并在设置初始状态时使用init()方法)。

这个方法让我很担心,因为我希望我的类在没有bean基础结构的情况下可用,就像Java对象一样。正如我想象的那样,我必须在每个方法断言样式中检查对象的正确状态。

上述快速演示:

class A {
    public int x;
    public int y;
    private int sum;

    private boolean initialized = false;

    public void init() {
        sum = x + y;
        initialized = true;
    }

    private void initCheck() {
        if (!initialized) {
            throw new IllegalStateException("Uninitialized object.");
        }
    }

    public int getXMulSum() {
        initCheck();
        return x * sum;
    }

    public int getYMulSum() {
        initCheck();
        return y * sum;
    }

}

有更好的做法吗?

2 个答案:

答案 0 :(得分:3)

鉴于您不想使用框架......

如果一个类在适合使用之前已经初始化,我宁愿使用构造函数。不要被博客和书籍所左右。为此目的,构造者就在那里。使用构造函数也消除了同步代码的任何要求。

我可以看到不使用构造函数的一个原因是,如果有很多初始化代码,并且可能是类外部的依赖项。如果构造函数中存在太多逻辑,那么它可能会使您的应用程序变得脆弱,并且难以从构造函数中的异常中恢复。在这种情况下,您可以选择使用Factory class来处理bean的实例化和初始化。这样,调用代码只接收一个准备就绪并且适合使用的bean

要使用的好模式是Builder pattern,其中有一长串构造函数参数。

"我观察到一种倾向(主要是使用bean)将所需参数从构造函数移动到setter"

这种可测试性的主要原因。如果您可以测试bean的功能而无需初始化"昂贵的"依赖关系,而不是在构造函数中没有它们是有益的。话虽如此,我还是会争辩说,如果这是一个问题,你可能在你的bean中有太多的功能,你最好不要分手。正如Single responsibility principle所建议的那样。

答案 1 :(得分:1)

setter比构造函数参数更通用,因为它们允许你处理循环依赖。

如果你没有循环依赖关系,我建议保留构造函数参数,exacly用于枚举依赖项。

但是,如果可能的话,不要将任何逻辑放入构造函数中。正如Brad所说,它使应用程序变得脆弱。构造函数中可能无法使用整个Spring环境。

尝试以允许构造函数简单地记住引用的方式进行设计,以便稍后在真正的方法中使用。如果可以,请避免使用init()方法。