With a Bloch Builder you get the default values like this:
//Get a fully configured Employee with default values Employee employee = employeeBuilder.build();
If that blows up, it doesn't offer default values.
//Get a fully configured builder with default values, but change only the salary //before finally building the Employee Employee employee = employeeBuilder.setSalary(5000).build();
Where this gets interesting is when you have more than one set of "default" values. In that case the sets of values need names.
EmployeeBuilder internBuilder = employeeBuilder.setSalary(5000);
This gives you a builder that defaults to intern employee values. You can send this off to other code that will set other settings before finally building it.
EmployeeBuilder grantExecutiveAccess(EmployeeBuilder employeeBuilder){ return employeeBuilder .setExecutiveBathroomKey(true) .setParkingPermit("A") ; }
Here the name of these "defaults" is executive access. This way if another set of "defaults" becomes relevant you just need to give them a name.
Now was that a factory? Doesn't look like a typical one. It takes the same type as it returns. It returns what it was passed after mutating it. Call it a shunt if you like.
If there was such a thing as an executive intern employee you could build them like this:
EmployeeBuilder internBuilder = employeeBuilder.setSalary(5000); Employee executiveIntern = EmployeeFactory .grantExecutiveAccess(internBuilder) .build() ;
The key lesson here is that builders are first class objects themselves. So you are perfectly allowed to pass them around.
As to whether this is a good idea, you have to admit this leaves you with a fair bit to digest. The charm of builders is that they are straight forward to use. If you're going to require mixing factories and builders when a flat builder with some extra keyboard typing solves the same problem you'd better have a problem complex enough to make that a poor choice. Having the ability to decouple intern construction code from executive construction code is nice. But do you really need it this badly?
The advantage of this method over adding some executive method to the builder is that adding the factory will leave the builder code untouched. Sometimes that's important. Just remember, you could also create a whole new builder. Just need a good name.
It should also be noted that when you take a Bloch Builder beyond just simulating named arguments you're heading into DSL territory. DSLs are very powerful but take a fair bit of work to set up. They should be reserved for cases where they will be used a lot to make up for that extra effort.
Factoryis probably not the right name as it will get confused with the actual Factory design pattern.new EmployeeBuilder().build()to create an instance with the default values (this makes sense, but may not be obvious to everyone, so make sure to point this out in the docs and/or documentation comments associated with the builder class).