From c20ee75910bfee9f80aeb5245c5d21d43f691941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Fri, 24 May 2024 16:36:03 +0300 Subject: [PATCH] docs: update builder --- builder/README.md | 83 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 26 deletions(-) diff --git a/builder/README.md b/builder/README.md index af8fff28e..ae4cf5e9c 100644 --- a/builder/README.md +++ b/builder/README.md @@ -4,6 +4,8 @@ category: Creational language: en tag: - Gang of Four + - Instantiation + - Object composition --- ## Intent @@ -14,7 +16,7 @@ Separate the construction of a complex object from its representation so that th Real-world example -> Imagine a character generator for a role-playing game. The easiest option is to let the computer create the character for you. If you want to manually select the character details like profession, gender, hair color, etc. the character generation becomes a step-by-step process that completes when all the selections are ready. +> Imagine you are building a customizable sandwich at a deli. The Builder design pattern in this context would involve a SandwichBuilder that allows you to specify each component of the sandwich, such as the type of bread, meat, cheese, vegetables, and condiments. Instead of having to know how to construct the sandwich from scratch, you use the SandwichBuilder to add each desired component step-by-step, ensuring you get exactly the sandwich you want. This separation of construction from the final product representation ensures that the same construction process can yield different types of sandwiches based on the specified components. In plain words @@ -24,17 +26,20 @@ Wikipedia says > The builder pattern is an object creation software design pattern with the intentions of finding a solution to the telescoping constructor antipattern. -Having said that let me add a bit about what telescoping constructor antipattern is. At one point or the other, we have all seen a constructor like below: +That said, let's clarify what telescoping constructor antipattern is. At one point or the other, we have all seen a constructor like below: ```java public Hero(Profession profession,String name,HairType hairType,HairColor hairColor,Armor armor,Weapon weapon){ - } + // Value assignments +} ``` As you can see the number of constructor parameters can quickly get out of hand, and it may become difficult to understand the arrangement of parameters. Plus this parameter list could keep on growing if you would want to add more options in the future. This is called telescoping constructor antipattern. **Programmatic Example** +Imagine a character generator for a role-playing game. The easiest option is to let the computer create the character for you. If you want to manually select the character details like profession, gender, hair color, etc. the character generation becomes a step-by-step process that completes when all the selections are ready. + The sane alternative is to use the Builder pattern. First of all, we have our hero that we want to create: ```java @@ -105,12 +110,39 @@ Then we have the builder: Then it can be used as: ```java -var mage=new Hero.Builder(Profession.MAGE,"Riobard").withHairColor(HairColor.BLACK).withWeapon(Weapon.DAGGER).build(); + public static void main(String[] args) { + + var mage = new Hero.Builder(Profession.MAGE, "Riobard") + .withHairColor(HairColor.BLACK) + .withWeapon(Weapon.DAGGER) + .build(); + LOGGER.info(mage.toString()); + + var warrior = new Hero.Builder(Profession.WARRIOR, "Amberjill") + .withHairColor(HairColor.BLOND) + .withHairType(HairType.LONG_CURLY).withArmor(Armor.CHAIN_MAIL).withWeapon(Weapon.SWORD) + .build(); + LOGGER.info(warrior.toString()); + + var thief = new Hero.Builder(Profession.THIEF, "Desmond") + .withHairType(HairType.BALD) + .withWeapon(Weapon.BOW) + .build(); + LOGGER.info(thief.toString()); +} +``` + +Program output: + +``` +16:28:06.058 [main] INFO com.iluwatar.builder.App -- This is a mage named Riobard with black hair and wielding a dagger. +16:28:06.060 [main] INFO com.iluwatar.builder.App -- This is a warrior named Amberjill with blond long curly hair wearing chain mail and wielding a sword. +16:28:06.060 [main] INFO com.iluwatar.builder.App -- This is a thief named Desmond with bald head and wielding a bow. ``` ## Class diagram -![alt text](./etc/builder.urm.png "Builder class diagram") +![Builder](./etc/builder.urm.png "Builder class diagram") ## Applicability @@ -120,11 +152,22 @@ Use the Builder pattern when * The construction process must allow different representations for the object that's constructed * It's particularly useful when a product requires a lot of steps to be created and when these steps need to be executed in a specific sequence +## Tutorials + +* [Builder Design Pattern in Java (DigitalOcean)](https://www.journaldev.com/1425/builder-design-pattern-in-java) +* [Builder (Refactoring Guru)](https://refactoring.guru/design-patterns/builder) +* [Exploring Joshua Bloch’s Builder design pattern in Java (Java Magazine)](https://blogs.oracle.com/javamagazine/post/exploring-joshua-blochs-builder-design-pattern-in-java) + ## Known Uses -* Java.lang.StringBuilder +* StringBuilder in Java for constructing strings. +* java.lang.StringBuffer used to create mutable string objects. * Java.nio.ByteBuffer as well as similar buffers such as FloatBuffer, IntBuffer, and others * javax.swing.GroupLayout.Group#addComponent() +* Various GUI builders in IDEs that construct UI components. +* All implementations of [java.lang.Appendable](http://docs.oracle.com/javase/8/docs/api/java/lang/Appendable.html) +* [Apache Camel builders](https://github.com/apache/camel/tree/0e195428ee04531be27a0b659005e3aa8d159d23/camel-core/src/main/java/org/apache/camel/builder) +* [Apache Commons Option.Builder](https://commons.apache.org/proper/commons-cli/apidocs/org/apache/commons/cli/Option.Builder.html) ## Consequences @@ -138,29 +181,17 @@ Benefits: Trade-offs: * The overall complexity of the code can increase since the pattern requires creating multiple new classes - -## Tutorials - -* [Refactoring Guru](https://refactoring.guru/design-patterns/builder) -* [Oracle Blog](https://blogs.oracle.com/javamagazine/post/exploring-joshua-blochs-builder-design-pattern-in-java) -* [Journal Dev](https://www.journaldev.com/1425/builder-design-pattern-in-java) - -## Known uses - -* [java.lang.StringBuilder](http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html) -* [java.nio.ByteBuffer](http://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html#put-byte-) as well as similar buffers such as FloatBuffer, IntBuffer and so on. -* [java.lang.StringBuffer](http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuffer.html#append-boolean-) -* All implementations of [java.lang.Appendable](http://docs.oracle.com/javase/8/docs/api/java/lang/Appendable.html) -* [Apache Camel builders](https://github.com/apache/camel/tree/0e195428ee04531be27a0b659005e3aa8d159d23/camel-core/src/main/java/org/apache/camel/builder) -* [Apache Commons Option.Builder](https://commons.apache.org/proper/commons-cli/apidocs/org/apache/commons/cli/Option.Builder.html) +* May increase memory usage due to the necessity of creating multiple builder objects ## Related patterns -* [Step Builder](https://java-design-patterns.com/patterns/step-builder/) is a variation of the Builder pattern that generates a complex object using a step-by-step approach. The Step Builder pattern is a good choice when you need to build an object with a large number of optional parameters, and you want to avoid the telescoping constructor antipattern. +* [Abstract Factory](https://java-design-patterns.com/patterns/abstract-factory/): Can be used in conjunction with Builder to build parts of a complex object. +* [Prototype](https://java-design-patterns.com/patterns/prototype/): Builders often create objects from a prototype. +* [Step Builder](https://java-design-patterns.com/patterns/step-builder/): It is a variation of the Builder pattern that generates a complex object using a step-by-step approach. The Step Builder pattern is a good choice when you need to build an object with a large number of optional parameters, and you want to avoid the telescoping constructor antipattern. ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) -* [Effective Java](https://www.amazon.com/gp/product/0134685997/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0134685997&linkCode=as2&tag=javadesignpat-20&linkId=4e349f4b3ff8c50123f8147c828e53eb) -* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) -* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3w0pvKI) +* [Effective Java](https://amzn.to/4cGk2Jz) +* [Head First Design Patterns: Building Extensible and Maintainable Object-Oriented Software](https://amzn.to/49NGldq) +* [Refactoring to Patterns](https://amzn.to/3VOO4F5)