Why to use #newBuilder() function in Builder Pattern? Is it mandatory? - java

I am using the Builder Pattern since time ago, but these days one of my collegues reach me with a question to which I never thought about, and is about the #newBuilder() function in the Builder Pattern.
I've seen in several forums, tutorials, and even APIs, that when using the Builder Pattern, a structure like this is usually used:
Car car1 = new CarBuilder().newBuilder().twoDoors().fourWheels().build();
Usually, inside of the #newBuilder() function, there is a code like this:
public static CarBuilder newBuilder(){
return new CarBuilder();
}
The question is, why should be needed a #newBuilder() function in the Builder class? Is it a good practice to have it, or is needed only when overloading is applied? I mean, just in the cases where I need to overload the #newBuilder() having 2 or 3 different #newBuilder() functions with different parameters.
What if I will have only one #newBuilder() function in the Builder class? Should I implement it, or can I avoid it and do something like:
Car car1 = new CarBuilder().twoDoors().fourWheels().build();
The question of my colleague was: If I implement the #newBuilder() function, am I falling in redundancy with the first example if I will only have one #newBuilder() function in my Builder class?
What you think about this? Should I remove it or it is justified to have the #newBuilder() function despite of I have only one implementation of it without overloading?
Thanks!

Note that this:
Car car1 = new CarBuilder().newBuilder().twoDoors().fourWheels().build();
Is definitely redundant, but not because the newBuilder() method exists. The problem is your code is essentially this:
CarBuilder builder1 = new CarBuilder();
CarBuilder builder2 = builder1.newBuilder();
Car car1 = builder2.twoDoors().fourWheels().build();
In other words, you're creating two instances of CarBuilder. Also, you're calling a static method on an instance reference, which is frowned upon. With your current setup, your code should be either:
Car car1 = new CarBuilder().twoDoors().fourWheels().build();
OR:
Car car1 = CarBuilder.newBuilder().twoDoors().fourWheels().build();
Which style you choose is up to you. However, if you choose to use the second approach (the static factory method newBuilder()), then typically the builder's constructor is made private, or at least package-private, so that new CarBuilder() cannot be used by external code.
So, I would say "no", having newBuilder() is not redundant in and of itself, as long as you use it correctly. It's simply an alternative way of creating a builder instance without calling the constructor directly. Note using the static factory method approach may aid in readability, because you can name the method something more descriptive. You may not see that advantage unless you have a significant number of different factory methods with different semantics, however.
Another thing to consider is where to place the newBuilder() static method. If CarBuilder and Car are extremely coupled, then many developers will put the static method in the Car class instead of the CarBuilder class (if not just nest the latter in the former).
For example:
package sample;
public final class Car {
public static CarBuilder newBuilder() {
return new CarBuilder();
}
private final int numberOfDoors;
private final int numberOfWheels;
Car(CarBuilder builder) {
this.numberOfDoors = builder.numberOfDoors;
this.numberOfWheels = builder.numberOfWheels;
}
// getters and setters omitted for brevity
}
package sample;
public final class CarBuilder {
private int numberOfDoors; // should initialize to sensible default
private int numberOfWheels; // should initialize to sensible default
CarBuilder() {}
public CarBuilder twoDoors() {
numberOfDoors = 2;
return this;
}
public CarBuilder fourWheels() {
numberOfWheels = 4;
return this;
}
public Car build() {
return new Car(this);
}
}
Which could then be used like so:
Car car1 = Car.newBuilder().twoDoors().fourWheels().build();

Related

How to design Java class(es) that can optionally function as Singleton?

Here's the scenario:
public class A {
public A {}
void doSomething() {
// do something here...
}
}
Right now, the class is setup where you can create multiple instances. But I also see a need where I might want to restrict the class to only one instance, i.e. Singleton class.
The problem is I'm not sure how to go about the design of accomplishing both goals: Multiple instances and one instance. It doesn't sound possible to do in just one class. I imagine I'll need to use a derived class, an abstract class, interface, something else, or some combination.
Should I create class A as a base class and create a derived class which functions as the singleton class?
Of course, the first thing should always be to question the necessity to use singletons. But sometimes, they are simply a pragmatic way to solve certain problems.
If so, the first thing to understand is: there is no solution that can "enforce" your requirements and prevent mis-use, but here is a "pattern" that helps a lot by turning "intentions" into "meaningful" code:
First, I have an interface that denotes the functionality:
interface WhateverService { void foo() }
Then, I have some impl for that:
class WhateverServiceImpl implements WhateverService {
#Override
void foo() { .... }
Now, if I need that thing to exist as singleton, I do
enum WhateverServiceProvider implements WhateverService {
INSTANCE;
private final WhateverService impl = new WhateverServiceImpl();
#Override
void foo() { impl.foo() }
and finally, some client code can do:
WhateverService service = WhateverServiceProvider.INSTANCE;
service.foo()
(but of course, you might not want to directly assign a service object, but you could use dependency injection here)
Such architectures give you:
A clear separation between the core functionality, its implementation and the singleton concept
Guaranteed singleton semantics (if there is one thing that Java enums are really good for ... then it is that: providing fool-proof singletons!)
Full "testability" (you see - when you just use the enum, without making it available as interface ... then you have a hard time mocking that object in client code - as you can't mock enums directly).
Update - regarding thread safety:
I am not sure what exactly you mean with "singleton concept".
But lets say this: it is guaranteed that there is exactly one INSTANCE object instantiated when you use enums like that, the Java language guarantees that. But: if several threads are turning to the enum, and calling foo() in parallel ... you are still dealing with all the potential problems around such scenarios. So, yes, enum "creation" is thread-safe; but what your code is doing ... is up to you. So is then locking or whatever else makes sense.
I think you should take a look at this question:
Can a constructor in Java be private?
The Builder pattern described there could be a somewhat interesting solution:
// This is the class that will be produced by the builder
public class NameOfClassBeingCreated {
// ...
// This is the builder object
public static class Builder {
// ...
// Each builder has at least one "setter" function for choosing the
// various different configuration options. These setters are used
// to choose each of the various pieces of configuration independently.
// It is pretty typical for these setter functions to return the builder
// object, itself, so that the invocations can be chained together as in:
//
// return NameOfClassBeingCreated
// .newBuilder()
// .setOption1(option1)
// .setOption3(option3)
// .build();
//
// Note that any subset (or none) of these setters may actually be invoked
// when code uses the builer to construct the object in question.
public Builder setOption1(Option1Type option1) {
// ...
return this;
}
public Builder setOption2(Option2Type option2) {
// ...
return this;
}
// ...
public Builder setOptionN(OptionNType optionN) {
// ...
return this;
}
// ...
// Every builder must have a method that builds the object.
public NameOfClassBeingCreated build() {
// ...
}
// The Builder is typically not constructible directly
// in order to force construction through "newBuilder".
// See the documentation of "newBuilder" for an explanation.
private Builder() {}
}
// Constructs an instance of the builder object. This could
// take parameters if a subset of the parameters are required.
// This method is used instead of using "new Builder()" to make
// the interface for using this less awkward in the presence
// of method chaining. E.g., doing "(new Foo.Builder()).build()"
// is a little more awkward than "Foo.newBuilder().build()".
public static Builder newBuilder() {
return new Builder();
}
// ...
// There is typically just one constructor for the class being
// constructed that is private so that it may only be invoked
// by the Builder's "build()" function. The use of the builder
// allows for the class's actual constructor to be simplified.
private NameOfClassBeingCreated(
Option1Type option1,
Option2Type option2,
// ...
OptionNType optionN) {
// ...
}
}
Link for reference:
https://www.michaelsafyan.com/tech/design/patterns/builder
I am not sure that this is what you are looking for, but you can use Factory pattern. Create 2 factories, one will always return the same singleton, while the other one will create a new A object each time.
Factory singletonFactory = new SingetonFactory();
Factory prototypeFactory = new PrototypeFactory();
A a = singletonFactory.createA();
A b = singletonFactory.createA();
System.out.println(a == b); // true
A c = prototypeFactory.createA();
A d = prototypeFactory.createA();
System.out.println(c == d); // false
class A {
private A() {}
void doSomething() { /* do something here... */}
}
interface Factory {
A createA();
}
class SingetonFactory implements Factory {
private final A singleton = new A();
public A createA() {
return singleton;
}
}
class PrototypeFactory implements Factory {
public A createA() {
return new A();
}
}

How to make all Builder methods required?

I am constructing a car class that has an engine, gearbox, clutch etc.
I don't want a bloated constructor that takes 7 parameters, so I decided to use the builder pattern.
All the parts are required.
However, how do I make the user of the Car class use all the parts' setters, as they are all mandatory?
Throw exceptions?
public class Car {
private Engine engine;
private Chassis chassis;
private GearBox gearBox;
private Coupe coupe;
private Exterior exterior;
private Interior interior;
private Clutch clutch;
public Car(Builder builder) {
engine = builder.engine;
chassis = builder.chassis;
gearBox = builder.gearBox;
coupe = builder.coupe;
exterior = builder.exterior;
interior = builder.interior;
clutch = builder.clutch;
}
public static class Builder {
private Engine engine;
private Chassis chassis;
private GearBox gearBox;
private Coupe coupe;
private Exterior exterior;
private Interior interior;
private Clutch clutch;
private Car build() {
return new Car(this);
}
public Builder setEngine(#NonNull Engine engine) {
this.engine = engine;
return this;
}
public Builder setChassis(#NonNull Chassis chassis) {
this.chassis = chassis;
return this;
}
public Builder setGearBox(#NonNull GearBox gearBox) {
this.gearBox = gearBox;
return this;
}
public Builder setCoupe(#NonNull Coupe coupe) {
this.coupe = coupe;
return this;
}
public Builder setExterior(#NonNull Exterior exterior) {
this.exterior = exterior;
return this;
}
public Builder setInterior(#NonNull Interior interior) {
this.interior = interior;
return this;
}
public Builder setClutch(#NonNull Clutch clutchs) {
this.clutch = clutchs;
return this;
}
}
}
I want the user so call ALL of the builder setters, not an optional subset of them. How do I do that?
Is there another way to construct a car without having a huge constructor that takes so many parameters?
EDIT: I looked at The builder pattern and a large number of mandatory parameters but there is no solution there that prevents huge constructors.
Builders are for things where lots of parts are optional or you have many different configurations. The build() method then makes sure that the specific configuration works. A HTML builder makes sense, a string builder not so much.
If there are no optional parts, you have these options:
Get rid of the builder and use a constructor that requires all parts. Classic solution, least readable and hard to extend.
You can throw an exception in the build() method for each missing part. That's a lot of code to write and kind of goes against the pattern.
You can add methods with more than a single argument to the builder. That's a mix of the two above. You're still using the builder pattern (so you can easily add more configurations later) but your API also communicates more clearly which parts are mandatory.
As an example, you might get an engine in the future which already contains the gearbox or which requires a specific gearbox (i.e. when you use this engine, you also select the gearbox). To implement this, you'd create a second builder method which just asks for the engine and determines the gearbox automatically.
Use a factory with protected methods which build the parts. The factory will make sure all parts are supplied to the car. If you want to replace a part, you can override the protected method. This works well if you have lot of defaults and only 2-3 useful configurations.
Use several builders. Instead of build everything from individual screws, create your car from larger building blocks: propulsion, interior, body. Create your car from those three with a constructor (three parameters is good). Now you can use three builders to create those three. Try to find a balance between required and optional elements.
Chain builders as explained by mlk below. This forces the user to fill in all parts (since you can only call the build() at the end of the chain). Main drawbacks here are: A lot of code to write and hard to follow from the user perspective since the code is spread over many classes. jOOQ is an example here; the project implements the SQL syntax as a chain of builders.
Remember what the builder pattern tries to solve: They make it easy to add more parts since all existing code doesn't need to change if the new part is optional. If the new part is mandatory, the builder pattern becomes a liability: With a huge (unreadable) constructor, you get compile errors in all places that needs fixing. The builder will fail at runtime in this case; you need an IDE to find all the places which need fixing.
If the primary reason for this is to have a fluent API rather than removing a bloated constructor then you could chain builders together:
class Engine {}
class Door {}
class Car {
Car(Engine engine, Door door) {
}
}
class CarBuilder {
private Engine engine;
public CarWithEngineBuilder withEngine(Engine engine) {
this.engine = engine;
return new CarWithEngineBuilder();
}
class CarWithEngineBuilder {
private Door door;
public CarWithEngineAndDoor withDoor(Door door) {
this.door = door;
return new CarWithEngineAndDoor();
}
class CarWithEngineAndDoor {
public Car build() {
return new Car(engine, door);
}
}
}
}
class TestStuff {
{
Car c = new CarBuilder().withEngine(new Engine()).withDoor(new Door()).build();
}
}
Or if your main concern is the size of the constructor, maybe the constructor is telling you something, and you could look at the class and see is some parts are logically "together". I.e. are Engine, Gears & Brake are one part of larger component? Should the car be DriveSystem and Chassis (which includes an Exteriorand Interior). Then constructor for Car has a manageable number of parameters, as does DriveSystem and Chassis?
If you look to the builder pattern, you can find out, that there is important thing, which you do not have, and it is Director. And also Builder interface, that defines all the required methods.
Director should call all methods required on interface builder (in your case "build engine, build coupe etc."). The class implementing the Builder interface must override all methods or the code does not even compile.

Factory Method pattern vs composition

From GoF chapter about the Factory Method pattern:
Define an interface for creating an object, but let subclasses decide which class to
instantiate. Factory Method lets a class defer instantiation to subclasses.
The idea is to let subclasses decided which class to instantiate, and GoF's implementation of the idea, is to provide an abstract method in the superclass, that subclasses need to override, and thus providing their own instantiation logic.
What I don't understand is, why implementing it using an abstract method, and not using a class member which is the factory. I'll explain.
This is the GoF way:
public abstract class Creator {
public void doStuff() {
Product product = createProduct();
/* etc. */
}
public abstract Product createProduct();
}
Usage:
MyCreator myCreator = new Creator() {
#Override
public Product createProduct() {
return new MyProduct();
}
}
myCreator.doStuff();
But why bother with the subclassing, etc.? I suggest this approach:
public class Creator {
private Factory factory;
/* constructor */
public Creator(Factory factory) {
this.factory = factory;
}
public void doStuff() {
Product product = factory.createProduct();
/* etc. */
}
}
And this is how you use it:
MyFactory myFactory = new MyFactory();
Creator creator = new Creator(myFactory);
creator.doStuff();
So what is the benefit in GoF's approach? Why not composing the Factory into the Creator class instead of expressing it using an abstract method?
Why not composing the Factory into the Creator class instead of expressing it using an abstract method?
Because in that case the client "knows" what Factory class to instantiate which defeats the whole purpose of the pattern. The whole idea is that the client is oblivious as what factory is built, it only makes a call to an Abstract class. Think that you plugin-in to your framework some third party factory provider and you have no idea what they instantiate (and also don't care) as long as serves the purpose.
The Factory Method Pattern is used to give subclasses control over the type of object they generate. In your case, it is not the subclass that controls the type of object but the user of the class.
The following example is copies from the Wikipedia entry on the Factory Method Pattern. We have a maze game which exists in two variants: the normal maze game and a magic maze game with adapted rules. The normal maze game consists of normal rooms and the magic maze game of magic rooms.
public class MazeGame {
public MazeGame() {
Room room1 = makeRoom();
Room room2 = makeRoom();
room1.connect(room2);
this.addRoom(room1);
this.addRoom(room2);
}
protected Room makeRoom() {
return new OrdinaryRoom();
}
}
public class MagicMazeGame extends MazeGame {
#Override
protected Room makeRoom() {
return new MagicRoom();
}
}
By using the Factory Method Pattern we can make sure that the MagicMazeGame consists of MagicRooms but we can still re-use parts of the superclass.
In your suggestion the MazeGame class would be changed to:
public class MazeGame {
public MazeGame(RoomFactory factory) {
Room room1 = factory.makeRoom();
Room room2 = factory.makeRoom();
room1.connect(room2);
this.addRoom(room1);
this.addRoom(room2);
}
}
and now it would be possible to do:
MazeGame game1 = new MazeGame(new MagicRoomFactory());
MazeGame game2 = new MagicMazeGame(new OrdinaryRoomFactory());
which is something you would like to prevent because then MazeGames with the wrong kind of rooms in it can be created.
its often useful in these types of situations to use actual English types for illustrations rather than more abstract terms like "Product"
So, let's take Pets, and say that every (sub-)type of Pet has a Home (eg. Dog has a Kennel).
For your example, we would have :
Public void doStuff() {
Home home = factory.createHome();
}
But in this case, where does the logic go that says Dogs get Kennels, and Birds get Cages? It would have to go in the factory object - which in turns means that the inheritance hierarchy of Pets would have to be explicitly repeated in the Factory logic. This in turn means that every time you add a new type of Pet, you'll have to remember to add that type to the Factory as well.
The factory method pattern means that you'd have something like :
public class Pet {
private String name;
private Home home;
public Pet(String name) {
this.name = name;
this.home = this.createHome();
}
public abstract Home createHome();
This allows that every time you create a new type of Pet, you can specify that Pet type's home without having to change any other class, and in the process also know that every Pet type DOES have a Home.
Eg. You would have :
public class Dog extends Pet {
public Home createHome() {
return new Kennel();
}
}
Edited to add Dog example
I think that the answers to this question aren't totally satisfactory, so here's my two cents...
To quote #Hoopje's answer, we might end up with something like this:
public class MazeGame {
public MazeGame(RoomFactory factory) {
Room room1 = factory.makeRoom();
Room room2 = factory.makeRoom();
room1.connect(room2);
this.addRoom(room1);
this.addRoom(room2);
}
}
and then
MazeGame game1 = new MazeGame(new MagicRoomFactory());
MazeGame game2 = new MagicMazeGame(new OrdinaryRoomFactory());
As has been discussed above, this is nonsensical. However, I would contend that those last two lines don't make sense anyway, because in the OP's opinion, you would never need to create a MagicMazeGame at all. Instead you would just instantiate a MazeGame passing in new MagicRoomFactory().
MazeGame magicOne = new MazeGame(new MagicRoomFactory());
MazeGame normalOne = new MazeGame(new OrdinaryRoomFactory());
However, let's imagine that our MazeGame has multiple factories. Let's say that as well as needing to have a room factory, it also needs to have a points factory, and also a monsters factory. In this situation, we might end up with all of this being forced into the MazeGame constructor, like this:
public MazeGame(RoomFactory rmFactory, PointsFactory pointsFactory, MonsterFactory monstersFactory)
This is fairly convoluted, and instead it would be better to create concrete subclasses that each control their own type of game. That long constructor looks like a code smell to me too, though someone more knowledgeable might be able to add to this.
What's more, this means that whichever object is instantiating the game has to know about all of these inner-working classes, which breaks encapsulation.
All in all, by doing it this way we are giving too much control to the client, who doesn't want to know about all of these implementation details.
That's how I see it anyway...

Do we need a .build() method in the Builder Pattern?

I had a question regarding the "Builder Pattern" covered in "Effective Java". Do we need a .build() method for it to correctly implement the pattern? For instance, let's say that we have the following class:
public class CoffeeDrink {
private int numEspressoShots;
private short milkType;
private boolean withWhip;
private CoffeeDrink() {
}
public static CoffeeDrink buildNewDrink() {
return new CoffeeDrink();
}
public CoffeeDrink withEspresso(int n) {
this.numEspressoShots = n;
return this;
}
public CoffeeDrink withMilkType(shot t) {
this.milkType = t;
return this;
}
public CoffeeDrink withWhip() {
this.withWhip = true;
return this;
}
}
And then how we use it:
CoffeeDrink c = CoffeeDrink.buildNewDrink()
.withEspresso(2)
.withMilkType(2)
.withWhip();
Would this still be valid if I don't have a static inner Builder class? I guess that one of the advantages is that it holds off from creating a new CoffeeDrink object until the method .build() is called, but I'm still creating a Builder object. Just seeking some clarifications.
No, this is not the Builder pattern. It's valid Java, and it will compile and run. But your buildNewDrink() method, whether it's called build() or buildNewDrink() or something else, is just a simple Factory Method that creates a CoffeeDrink. Those other methods are like setter methods that happen to return themselves.
The static nested Builder class is necessary. While holding off on creating the class instance, it can perform validation logic to ensure that an invalid object is not created. I'm not sure that there is an invalid state to a CoffeeDrink as you have it, but if it did, with your code, it would be possible to create a CoffeeDrink and have it in an invalid state after it was created, but before other methods were called. The Builder pattern eliminates this possibility by validating the data before building the instance. It also eliminates the need for constructor explosion, where lots of constructors with all possible combinations of parameters are needed, to cover all possible cases.
According to the GoF reference, build() isn't required. The original reference doesn't use chaining, and there is a getResult() step at the end of the Director.construct() method. The Director class takes care of encapsulating the build process, so Clients don't need to worry if they're building things correctly. It's the responsibility of the Director.
Here's the sequence diagram from the GoF reference on Builder:

object reference passed through constructor

Im building a relatively large object-oriented program. I have a class called AerodynamicCalculator that performs numerous calculations and distributes the results around the system. My main concern is that my constructor signature is getting larger and larger as I add mor parameters to it.
As shown below I already have nine object references being passed into this constructor, but I need a further seven. Am I correctly creating this object? My understanding is that you pass the associated object references to the constructor and assign the class'es local variable to the object references. If this is the case the only way to get my class properly initialized with all the required objects is to pass them to the constructor, which is leading to a very long signature.
public AreodynamicCalculator(AircraftConfiguration config, AileronOne aOne,
AileronTwo aTwo, ElevatorOne eOne, ElevatorTwo eTwo, Rudder r,
Rudder rr, RateGyros rG) {
// ...
}
Any advice on this approach would be very helpful, thanks in advance.
As mentioned - this may be a sign your class is doing too much, however, there is a commonly used 'solution' to this problem.
The builder pattern is often used in this situation, but it's also very useful when you have many constructors with different arguments, the builder is good because it makes the meaning of the arguments clearer, particularly when boolean literals are used.
Here is the builder pattern, the way this works is like this:
AreodynamicCalculator calc = AreodynamicCalculator.builder()
.config(theAircraftConfiguration)
.addAileron(aileronOne)
.addAileron(aileronTwo)
.addElevator(elevatorOne)
.addElevator(elevatorTwo)
.addRudder(rudderOne)
.addRudder(rudderTwo)
.build()
Internally, the builder will store all these fields, and when build() is called it will call a (now private) constructor that takes these fields:
class AreodynamicCalculator {
public static class Builder {
AircraftConfiguration config;
Aileron aileronOne;
Aileron aileronTwo;
Elevator elevatorOne;
Elevator elevatorTwo;
...
public Builder config(AircraftConfiguration config) {
this.config = config;
return this;
}
public Builder addAileron(Aileron aileron) {
if (this.aileronOne == null) {
this.aileronOne = aileron;
} else {
this.aileronTwo = aileron;
}
return this;
}
// adders / setters for other fields.
public AreodynamicCalculator build() {
return new AreodynamicCalculator(config, aileronOne, aileronTwo ... );
}
}
// this is the AircraftConfiguration constructor, it's now private because
// the way to create AircraftConfiguration objects is via the builder
//
private AircraftConfiguration config, AileronOne aOne, AileronTwo aTwo, ElevatorOne eOne, ElevatorTwo eTwo, Rudder r, Rudder rr, RateGyros rG) {
/// assign fields
}
}
Similarly to using the builder pattern, suggested in daveb's response, you can use a Dependency Injection framework like Spring.

Categories

Resources