Your comments
Thanks for your feedback! I'm delighted that you like my work!
Thanks a lot for your kind words! I'm delighted that you like my work.
Yes, they both will fail at runtime, but the reason for failure will be very different. The builder will likely fail at the initialization time of your app, with an exception condition programmed by you (and maybe even handled gracefully). In the other case, the failure will take place when the client is actually used (e.g. someone tries to place an order) with random consequences (maybe the order will be placed, or maybe not; maybe the price will be correct, or maybe not, etc; maybe the problem will manifest itself during refund, or some other time, etc.).
Hi!
Let me address the Director question first.
I'm pretty sure that if you take a group of 100 developers who claim to have used the Builder pattern and ask them to present their production code that uses Builder, you would see a designated Director class a handful of times.
This is because the main convenience of Builder nowadays is to construct products step-by-step with chaining. You would see something like this a lot more often than a full-blown implementation with a proper Director:
CarManual manual = (new CarManualBuilder()) .setSeats(4); .setDoors(5); .setColor('red'); .getProduct();
In most real-world cases, the products are of the same class hierarchy or interface (otherwise, you what would be the type of getProduct?), so it's fine to have that getProduct on the Builder. The classic implementation deals with the additional problem of having different product types. If you have that problem, you may solve it with the Director. If not, it's just an extra unnecessary class to maintain.
---
The second aspect, "why do you need a builder if you have all the building methods on the product".
The code in the post looks very similar indeed. However, there's an important difference. With the builder, the client only ever has access to the finished product.
If it doesn't feel intuitively that important, imagine that you're creating an API class for some payment provider like Stripe or something. A class like that should be initialized in a certain way: the user (a developer who integrates your API with their own service) has to supply their API keys, there should be some API endpoint set, maybe an API version, etc. When you go a Builder route, you can always validate all the configuration on the getProduct and throw an exception if the user fails to supply something BEFORE letting them call the actual API.
Let me show this with the code. This is the non-Builder version:
ApiClient client = new ApiClientBuilder();
client.key = '...';
// The client instance seems to be ready, but the developer forgot to specify // the API version, for example.
// In some other methods:
client.sendPaymentRequest(...) // The problem with missing API version will only manifest itself on the above call, // with random consequences.
Now, the same thing with Builder
ApiClient client = new ApiClientBuilder() .setKey(...) .getClient();
// The code can fail here, because in the implementation of getClient, // you can check all the important constraints and fail early if user // missed to call all the necessary build steps. // User never receives an instance of the api client, unless it's valid.
// In some other methods:
client.sendPaymentRequest(...) // This place won't ever be reached.
Hi!
Thanks, I agree with your point of view. I'll add it to my redesign to-do list.
¡Gracias por tus comentarios, Carlos! Me alegra que mi trabajo te haya sido útil.
Wow, thanks for your feedback! I'm delighted that you like my work.
Yeah, I knew about that one, it's one my favourites. I also love the one from Holub on Patterns: https://holub.com/goodies/holub_design_patterns.pdf
Hi!
I'm sorry, but the book hasn't been published as a hard copy so far. For now, you can only buy the digital version, which is available in PDF, ePub, Mobi, and KFX formats. You get access to the ebook right after purchase.
Customer support service by UserEcho
Thanks for the kind words! I appreciate your feedback.