views:

161

answers:

2

There is a code snippet presented in The Pragmatic Programmer on page 143 as:

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

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

This obeys the Law of Demeter / Principle of Least Knowledge.

Is it preferable to, and are there any caveats for, replacing it with the following, which utilises Dependency Injection?

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  A: 

public getInstance(), shouldn't that be "public static Colada getInstance()"?

Both are fine in my world, the first one more readable, the second one more dynamic. But neither of them suggest that myBlender and myStuff are properties, thus it's hard to see why you'd prefer it dynamic. But if that's what you want, it looks all right. Instead of getInstance I'd just make two constructors, though, one with no arguments like the first example and one with two like the second

Cheers

Nik

niklassaers
+1 for two constructors instead of getInstance.
Thilo
Fixed the static factory method declaration. re:"it's hard to see why you'd prefer it dynamic." => It's habituation in regards to the ability to perform unit testing.
_ande_turner_
+2  A: 

How you structure creation of objects are a separate concern than the API it exposes.

The Law of Demeter says something about the API of classes, not how they are constructed, so I see no conflict between Constructor Injection and the Law of Demeter.

That said, once you decide to use Dependency Injection, you should be careful to avoid ambiguity when it comes to creation of objects. If you keep offering a parameterless constructor or a static factory method, people may use this instead of letting the external caller compose the dependency hierarchy.

Every time developers accidentally break the dependency hierarchy by using the factory method (or paramterless constructor) they introduce a tight coupling at that point. When you decide to use DI, you can best harvest the benefits from doing so consistently.

Mark Seemann