Background
I have a class TextDrawable which draws text on top of a shape. There are a number of properties that can be set while creating a TextDrawable object.
Mandatory Properties:
- Text
- Shape
Optional Properties:
- Color
- Width
- Height
- Font
- Border
- ...
- ... etc.
The class will have constructors that look like:
public TextDrawable(String text, Shape shape) { } public TextDrawable(String text, Shape shape, int color) { } public TextDrawable(String text, Shape shape, int color, int width, int height) { } // and so on.. Builder Pattern :
I decided to use the Builder Pattern to make it more convenient to create TextDrawable objects. I followed the design as explained in Effective Java, and here in this highly upvoted answer. I came up with the builder class which will be used as follows:
TextDrawable drawable = new TextDrawable.Builder("AK", Shape.RECT) .width(10) .height(10) .useFont(Typeface.DEFAULT_BOLD) .build(); Possible Problem:
There seems to be a problem with this design. Since the "mandatory" fields are passed in the constructor of the builder, the builder cannot be reused.
What if I wanted to create another TextDrawable of same height, width, font etc but with different text and color. I will have to create another builder object and repeat the same code as above.
TextDrawable oct = new TextDrawable.Builder("OCT", Shape.RECT) .width(10) .height(10) .useFont(Typeface.DEFAULT_BOLD) .build(); TextDrawable nov = new TextDrawable.Builder("NOV", Shape.OVAL) .width(10) .height(10) .useFont(Typeface.DEFAULT_BOLD) .build(); Proposed Method:
What if I move the mandatory parameters from the constructor of the builder to the build method as follows:
TextDrawable drawable = new TextDrawable.Builder() .width(10) .height(10) .useFont(Typeface.DEFAULT_BOLD) .build("AK", Shape.RECT); This way allows for more flexibility as I can create one instance of the builder and reuse it to create multiple objects. (Also avoids repeating the same code every time I create a new object.) The new usage will look something like:
TextDrawable.Builder builder = new TextDrawable.Builder() .width(10) .height(10) .useFont(Typeface.DEFAULT_BOLD); TextDrawable oct = builder.build("OCT", Shape.RECT); TextDrawable nov = builder.build("NOV", Shape.OVAL); It prevents boilerplate code. Also allows the build method to fit into the fluency idiom as follows:
TextDrawable oct = builder.buildRect("OCT"); TextDrawable nov = builder.buildOval("NOV"); Questions:
Is the problem identified above valid or do I lack understanding of the
builder pattern? Should we not reusebuilderobjects to created multiple instances?Is the proposed modification to the well known
builder patternvalid? Are there any disadvantages of moving the "mandatory fields" into thebuild()method?If there are some possible drawbacks, what is a better way of achieving what I want? Should I be using a
directorobject or something that encapsulates thebuilderto achieve what I want?