1

I'm currently working on the builder pattern. There is one thing that I don't get and it's the following. Let's say I want to create computers, laptop and desktop ones. Should I create a ComputerBuilder that would use a different process depending on the parameter I pass to it, or should I create a LaptopBuilder and a DesktopBuilder? I've seen both in code samples online. Wikipedia uses the second method in its pizza example. To me this looks more like the factory pattern, but I could use some external light on this. Thanks!

1 Answers1

1

Create an abstract builder and extend it to two concrete builder subclasses. This abstracts the logic out.

Here is some sample code. In this code, three standard methods are defined in the abstract class. The extending classes can choose which of these to implement. Finally, all abstract classes will implement the abstract method and return a computer.

public abstract class Builder {

    public void doSomethingA() {};
    public void doSomethingB() {};
    public void doSomethingC() {};
    public abstract Computer returnComputer();
}

Now, the LaptopBuilder class extends this abstract class and has its own versions of two of the methods:

public class LaptopBuilder {

    private Computer computer;

    public LaptopBuilder(Computer computer) {
        this.computer = computer;
    }

    public void doSomethingA() {
        System.out.println("Laptop Method A");
    }

    public void doSomethingB() {
        System.out.println("Laptop Method B");
    }

    public Computer returnComputer() {
        return computer;
    }
}

Finally, the DesktopBuilder class extends the abstract class and has its own versions of two of the methods:

public class DesktopBuilder {

    private Computer computer;

    public DesktopBuilder(Computer computer) {
        this.computer = computer;
    }

    public void doSomethingB() {
        System.out.println("Desktop Method B");
    }

    public void doSomethingC() {
        System.out.println("Desktop Method C");
    }

    public Computer returnComputer() {
        return computer;
    }
}

Now all that's needed is to create a director abstract class, along with a desktop and laptop concrete director:

public abstract class Director {
    public abstract Computer build(Builder builder);
}

public class LaptopDirector extends Director {
    public Computer build(Builder builder) {
        builder.doSomethingA();
        builder.doSomethingB();
        return builder.returnComputer();
    }
}

public class DesktopDirector extends Director {
    public Computer build(Builder builder) {
        builder.doSomethingB();
        builder.doSomethingC();
        return builder.returnComputer();
    }
}

Finally, in your client, just create your computer, create the relevant builder, create the relevant director and call the build method.

Edit: This post may also be of value: When would you use the Builder Pattern?

Community
  • 1
  • 1
Andrew Martin
  • 5,619
  • 10
  • 54
  • 92
  • Isn't this a factory method? –  May 21 '13 at 19:51
  • To my knowledge this is the Builder pattern. I've only started studying them this year, but I've taken this example almost directly out of Tony Bevis' "Design Pattern Essentials". – Andrew Martin May 21 '13 at 19:55
  • Your example is actually good. It is a builder in that both `Builder` classes do different things. For some reason I wasn't able to understand this until I saw an example in the GOF book where the developer had a public `doSomething()` function, which then called a private `doThing()`. This really made me grasp the idea of internal logic that can be different from builder to builder. To me Wikipedia's example still is a pretty poor example that doesn't show what the Builder can do. –  May 21 '13 at 22:01
  • @mm2703: I've an exam on this stuff coming up and I've frequently found that different websites use different versions of the design patterns, with some of the examples often blatantly wrong (i.e. the difference between factory method, abstract factory and simple factory). – Andrew Martin May 21 '13 at 22:02