实用程序员的练习26

时间:2010-03-19 07:22:51

标签: java dependency-injection law-of-demeter

第143页的The Pragmatic Programmer中提供了一个代码段:

public class Colada {
    private Blender myBlender;
    private Vector myStuff;

    public Colada() {
        myBlender = new Blender();
        myStuff = new Vector();
    }
    private doSomething() {
        myBlender.addIngredients(myStuff.elements());
    }
}

这符合得墨忒耳法/最少知识原则。

是否优先使用依赖注入替换它,并且是否有任何注意事项?

public class Colada throws IllegalArgumentException {
    private Blender myBlender;
    private Vector myStuff;

    public Colada(Blender blender, Vector stuff) {
        if (null == blender) {
            throw new IllegalArgumentException()
        } else {
            myBlender = blender;
        }
        if (null == stuff) {
            throw new IllegalArgumentException()
        } else {
           myStuff = stuff;
        }
    }

    public static Colada createDefaultInstance() {   
        Blender blender = new Blender();
        Vector stuff = new Vector();

        return new Colada(blender, stuff);
    }

    private doSomething() {
        myBlender.addIngredients(myStuff.elements());
    }
}

2 个答案:

答案 0 :(得分:4)

如何构建对象的创建是一个单独的问题,而不是它所公开的 API

Demeter法则说明了类的API,而不是它们是如何构造的,所以我看到构造函数注入和得墨忒耳法之间没有冲突。

也就是说,一旦您决定使用依赖注入,在创建对象时应该小心避免歧义。如果你继续提供无参数构造函数或静态工厂方法,人们可以使用它而不是让外部调用者组成依赖层次结构。

每次开发人员通过使用工厂方法(或无参数构造函数)意外破坏依赖关系层次结构时,他们会在该点引入紧耦合。当您决定使用DI时,您可以最好地从这样做中获益。

答案 1 :(得分:2)

public getInstance(),不应该是“public static Colada getInstance()”吗?

我的世界都很好,第一个更可读,第二个更有活力。但他们都没有暗示myBlender和myStuff是属性,因此很难理解为什么你更喜欢它的动态。但如果这就是你想要的,它看起来很好。而不是getInstance我只创建了两个构造函数,一个没有像第一个例子那样的参数,另一个像第二个那样有两个

干杯

的Nik