1

I have a class "MyClass". Object creation of MyClass is complex as it has 6 steps and some of them are dependent on previous steps. Is builder pattern a good use case for this scenario ? If yes, how do i do it ? Please advise.

Kindly reply if question is not clear and you need more inputs.

Code, (I have reduced the steps to 3 in sample code, in reality i have 6 steps where some are dependent on previous steps and has a total of 40 lines of code. So I am trying to see if I can build the object in a cleaner way).

public class MyClass{
private SomeObject3 obj3;
private SomeObject1 obj1;

public MyClass(ParamObject param)
{ 
    obj1 = new SomeObject1(param);
    SomeObject2 obj2 = new SomeObject2(obj1);
    obj3 = new SomeObject3(obj2);
}
}
shadowfax
  • 971
  • 1
  • 10
  • 17
  • I think I understand your question, but I don't how the code you have posted has anything to do with builders and required ordering of calling builder functions. – aliteralmind Jul 05 '14 at 17:16
  • Thanks for response. I need to create 6 objects and has more than 40 lines of code to do so. So I was trying to see if there is a cleaner way to build the object instead of writing those 40 lines in a constructor / single procedure. – shadowfax Jul 05 '14 at 17:19
  • You can enforce order with a highly complicated builder design, such as one containing functions that return `NotYetReaderBuilder`. Only the final function returns the actual `Builder` object. An alternative is to have functions in a normal builder (such as the [Bloch Builder](http://www.informit.com/articles/article.aspx?p=1216151&seqNum=2)) accept more than one parameter. So if step three requires the value of step two, have the builder function be `itemsTwoAndThree(o2, o3)`. The functions that don't depend on others can just be normal standalone functions (`name("Humphrey")`). – aliteralmind Jul 05 '14 at 17:36

2 Answers2

1

The builder pattern is not necessarily what you need since it has no way to enforce "order".

For example:

builder.setX(x)
       .setY(y)
       .setDepth(p);
builder.build();

should be equivalent to:

builder.setY(y)
       .setArea(p)
       .setX(x);
builder.build();

That said, you can "hide" steps in the builder, for example, do only:

builder.setX(x)
       .setY(y)
builder.build();

and in the implementation of both setX() and setY() check if both parameters are set, and if the answer is "yes" - call a private method setArea(x*y). In this example, you'll have to add a validation in: builder.build(); to see that x,y and area are all set, and if not - raise an IllegalStateException.

Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
0

You have different objects that depend on each other, so you need to follow an order while creating them. I think the builder pattern is not suitable here, what you need is dependency injection, so you will not need to think about all the dependencies and the order, IOC container (or something else) will take care of this for you. Check: What is dependency injection?

By this solution, you can have something like this for example:

public class MyClass {
    @Inject
    private SomeObject3 obj3;
    @Inject
    private SomeObject1 obj1;

    public MyClass() {
        // ...
    }
}

public class SomeObject1 {
    @Inject
    public SomeObject1(ParamObject paramObject) {
    }
}

public class SomeObject2 {
    @Inject
    public SomeObject2(SomeObject1 someObject1) {
        // ...
    }
}

public class SomeObject3 {
    @Inject
    public SomeObject3(SomeObject2 someObject2) {
    }
}
Community
  • 1
  • 1
Utku Özdemir
  • 7,390
  • 2
  • 52
  • 49