From 90bf2cb471fc648755bb1cde1ced01d5d85f4009 Mon Sep 17 00:00:00 2001 From: "Sonia A. Ribeiro" Date: Fri, 6 Oct 2023 00:01:16 +0100 Subject: [PATCH 1/4] Add example classes --- Design Patterns/Builder/README.md | 140 ++++++++++++++++++ .../Builder/com.builder.java/Dought.java | 3 + .../Builder/com.builder.java/Pizza.java | 53 +++++++ .../Builder/com.builder.java/Sauce.java | 3 + .../Builder/com.builder.java/Size.java | 3 + .../Builder/com.builder.java/Topping.java | 3 + 6 files changed, 205 insertions(+) create mode 100644 Design Patterns/Builder/README.md create mode 100644 Design Patterns/Builder/com.builder.java/Dought.java create mode 100644 Design Patterns/Builder/com.builder.java/Pizza.java create mode 100644 Design Patterns/Builder/com.builder.java/Sauce.java create mode 100644 Design Patterns/Builder/com.builder.java/Size.java create mode 100644 Design Patterns/Builder/com.builder.java/Topping.java diff --git a/Design Patterns/Builder/README.md b/Design Patterns/Builder/README.md new file mode 100644 index 0000000..eb797f9 --- /dev/null +++ b/Design Patterns/Builder/README.md @@ -0,0 +1,140 @@ +# Builder Pattern +O padrão **Builder**, que é um dos _23 padrões de design do +Gang of Four (GoF)_, é um padrão de criação +que permite construir objetos complexos passo a passo. +Além de encapsular a construção, é capaz de produzir diferentes +tipos e representações de um item utilizando o mesmo código. + +## Motivação +O padrão Builder foi introduzido para resolver alguns +dos problemas de outros padrões de design semelhantes, como +o **Factory** e **Abstract Factory**. + +Imagine uma classe que possua muitos atributos, sendo eles, +variados entre opcionais e obrigatórios. No momento de criação +de uma instância, os valores para os atributos obrigatórios sempre +precisarão existir. Entretanto, a variação desses objetos com os campos +opcionais pode ser enorme. + +Para solucionar e adequar os construtores aos casos conforme +a necessidade, tradicionalmente, é usado o conceito de +**construtor telescópico**: onde o primeiro construtor +ocupa apenas os campos obrigatórios, para cada campo opcional, +existe um construtor adicional que utiliza os campos obrigatórios +**mais** os campos opcionais. + +``` java +class Pizza { + public Pizza (Size size, Dough dought) { ... } + public Pizza (Size size, Dough dought, Sauce sauce) { ... } + public Pizza (Size size, Dough dought, Sauce sauce, List toppings) { ... } + // ... +} +``` + +O maior problema dessa solução, se dá pela manutenção desse +código e leitura a longo prazo, pois os construtores tendem +a aumentar conforme aumenta o número de atributos da classe. + +Outra possibilidade, é a utilização do **padrão JavaBeans**, ou +seja, a criação de um construtor sem parâmetros e setters +para inicialização dos valores necessários. + +```java + ... + Pizza pizza = new Pizza(); + pizza.setSize(SMALL); + pizza.setSauce(RED); + ... +``` + +Uma desvantagem relacionada é que o padrão JavaBeans +exclui a possibilidade de tornar uma classe imutável e +requer esforço adicional por parte do programador para +garantir a segurança da thread. Se eu esqueço um dos parâmetros +obrigatórios, como o tamanho, por exemplo, posso ter problemas +futuros na utilização desse objeto. + +Com o objetivo de resolver esses problemas, surgiu o padrão +Builder. + +Algumas vantagens e desvantagens dessa abordagem são: + + +| Vantagens | Desvantagens | +|------------------------------------------------------------|-----------------------------------------------------------------------| +| Encapsulamento bem definido | Sempre é necessário criar um builder para a instanciação de um objeto | +| Flexibilidade e possibilidade de customização de um objeto | Mais verboso que os demais métodos | +| Imutabilidade | | +| Segurança e integridade dos dados | | +| Reusabilidade de código | | +| Maior controle no processo de construção de um objeto | | + +## Exemplo + +No nosso caso de uso, temos a construção de uma `Pizza`. Temos +algumas possíveis variações aqui: Com ou sem azeitonas, +tipos diferentes de tamanho, tipos de massa, possibilidades +de molhos, quantidades e tipos de toppings +(ou sem, se você tiver gostos peculiares). + +A estrutura do projeto é a seguinte: +``` +. +├── ... +├── com.builder.java # Pacote destinado ao exemplo +│ ├── Dought # Enum de tipos de Massa +│ ├── Pizza # Classe da construção da Pizza +│ ├── Sauce # Enum de tipos de Molho +│ ├── Size # Enum de tipos de Tamanho +│ └── Topping # Enum de tipos de Toppings +├── README.md # Documentação do exemplo +└── ... + +``` + + +Uma forma de utilizar o padrão para a construção +dessas Pizzas é como no exemplo abaixo: + +``` java + Pizza sausagePizza = new PizzaBuilder(Size.SMALL, Dought.WHITE) + .withSauce(Sauce.RED) + .withTopping(Topping.CHEESE, Topping.SAUSAGE, Topping.ONION) + .withOlive() + .build(); + + Pizza cheesePizza = new PizzaBuilder(Size.LARGE, Dought.WHITE) + .withSauce(Sauce.WHITE) + .withTopping(Topping.CHEESE) + .build(); +``` + +## Casos de Uso +- [java.lang.StringBuilder](https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html) +- [java.lang.StringBuffer](https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuffer.html#append-boolean-) + +## Para saber mais +Os exemplos mostrados aqui, foram inspirados na versão do +padrão Builder de Joshua Bloch, autor do livro Effective Java. +Essa versão alternativa, é uma variação da versão original +apresentado pelo Gang of Four, que contém outros +elementos, entre eles, um Director, responsável +por notificar o construtor sempre que uma parte do produto +deve ser construída. + +Caso tenha curiosidade, o livro **Design Patterns: Elements of Reusable Object-Oriented Software**, +o site do Refactor Guru e livro Head First Design Patterns, +todos presentes na seção **Fonte**, abordam o padrão +em sua forma original. + + +## Fonte +- [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional-ebook/dp/B000SEIBB8) +- [Refactoring Guru](https://refactoring.guru/design-patterns/builder) +- Head First Design Patterns +- Effective Java +- [DigitalOcean](https://www.digitalocean.com/community/tutorials/builder-design-pattern-in-java) +- [JournalDev: Builder Design Pattern](https://www.youtube.com/watch?v=D5NK5qMM14g&ab_channel=JournalDevITServices) +- [Exploring Joshua Bloch’s Builder design pattern in Java](https://blogs.oracle.com/javamagazine/post/exploring-joshua-blochs-builder-design-pattern-in-java) + diff --git a/Design Patterns/Builder/com.builder.java/Dought.java b/Design Patterns/Builder/com.builder.java/Dought.java new file mode 100644 index 0000000..57778ce --- /dev/null +++ b/Design Patterns/Builder/com.builder.java/Dought.java @@ -0,0 +1,3 @@ +enum Dought { + WHEAT, WHITE; +} diff --git a/Design Patterns/Builder/com.builder.java/Pizza.java b/Design Patterns/Builder/com.builder.java/Pizza.java new file mode 100644 index 0000000..5cceb2e --- /dev/null +++ b/Design Patterns/Builder/com.builder.java/Pizza.java @@ -0,0 +1,53 @@ +import java.util.*; + +import static java.util.Arrays.stream; + +public class Pizza { + + private final Size size; + private final Dought dought; + private final Sauce sauce; + private final Set toppings; + private boolean olive; + + public static class PizzaBuilder { + private final Size size; + private final Dought dought; + private Sauce sauce; + private EnumSet toppings = EnumSet.noneOf(Topping.class); + private boolean olive; + + public PizzaBuilder(Size size, Dought dought) { + this.size = size; + this.dought = dought; + } + + public PizzaBuilder withTopping(Topping... topping) { + toppings.addAll(stream(topping).toList()); + return this; + } + + public PizzaBuilder withSauce(Sauce sauce) { + this.sauce = sauce; + return this; + } + + public PizzaBuilder withOlive() { + this.olive = true; + return this; + } + + public Pizza build() { + return new Pizza(this); + } + + + } + private Pizza(PizzaBuilder builder) { + this.size = builder.size; + this.dought = builder.dought; + this.sauce = builder.sauce; + this.toppings = builder.toppings; + this.olive = builder.olive; + } +} \ No newline at end of file diff --git a/Design Patterns/Builder/com.builder.java/Sauce.java b/Design Patterns/Builder/com.builder.java/Sauce.java new file mode 100644 index 0000000..d752909 --- /dev/null +++ b/Design Patterns/Builder/com.builder.java/Sauce.java @@ -0,0 +1,3 @@ +enum Sauce { + WHITE, RED; +} diff --git a/Design Patterns/Builder/com.builder.java/Size.java b/Design Patterns/Builder/com.builder.java/Size.java new file mode 100644 index 0000000..d07d688 --- /dev/null +++ b/Design Patterns/Builder/com.builder.java/Size.java @@ -0,0 +1,3 @@ +public enum Size { + SMALL, MEDIUM, LARGE; +} diff --git a/Design Patterns/Builder/com.builder.java/Topping.java b/Design Patterns/Builder/com.builder.java/Topping.java new file mode 100644 index 0000000..d8eae2b --- /dev/null +++ b/Design Patterns/Builder/com.builder.java/Topping.java @@ -0,0 +1,3 @@ +enum Topping { + HAM, MUSHROOM, CORN, ONION, SAUSAGE, CHEESE; +} From b4e22df8e3917d8a93aef497bdbc0b46751d40be Mon Sep 17 00:00:00 2001 From: "Sonia A. Ribeiro" Date: Fri, 6 Oct 2023 00:01:50 +0100 Subject: [PATCH 2/4] Edit iml --- java-trainning.iml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 java-trainning.iml diff --git a/java-trainning.iml b/java-trainning.iml new file mode 100644 index 0000000..b7bb9bc --- /dev/null +++ b/java-trainning.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file From ea7b5dc6eb2a3a60e1c8b4660414391a06e1ee80 Mon Sep 17 00:00:00 2001 From: "Sonia A. Ribeiro" Date: Fri, 6 Oct 2023 00:03:55 +0100 Subject: [PATCH 3/4] Add links to README --- Design Patterns/Builder/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Design Patterns/Builder/README.md b/Design Patterns/Builder/README.md index eb797f9..ca38a6a 100644 --- a/Design Patterns/Builder/README.md +++ b/Design Patterns/Builder/README.md @@ -132,8 +132,8 @@ em sua forma original. ## Fonte - [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional-ebook/dp/B000SEIBB8) - [Refactoring Guru](https://refactoring.guru/design-patterns/builder) -- Head First Design Patterns -- Effective Java +- [Head First Design Patterns](https://www.amazon.com.br/Cabe%C3%A7a-Padr%C3%B5es-Projetos-Eric-Freeman/dp/8576081741) +- [Effective Java](https://www.amazon.com.br/Effective-Java-English-Joshua-Bloch-ebook/dp/B078H61SCH/ref=sr_1_1?__mk_pt_BR=%C3%85M%C3%85%C5%BD%C3%95%C3%91&crid=2VO8TOTTXMH5Y&keywords=effective+java&qid=1696547006&s=books&sprefix=effective+java%2Cstripbooks%2C148&sr=1-1) - [DigitalOcean](https://www.digitalocean.com/community/tutorials/builder-design-pattern-in-java) - [JournalDev: Builder Design Pattern](https://www.youtube.com/watch?v=D5NK5qMM14g&ab_channel=JournalDevITServices) - [Exploring Joshua Bloch’s Builder design pattern in Java](https://blogs.oracle.com/javamagazine/post/exploring-joshua-blochs-builder-design-pattern-in-java) From f5dc387738766d498a8f89abf627611be71cd63c Mon Sep 17 00:00:00 2001 From: "Sonia A. Ribeiro" Date: Fri, 6 Oct 2023 00:16:24 +0100 Subject: [PATCH 4/4] Change flour's name --- Design Patterns/Builder/README.md | 4 ++-- Design Patterns/Builder/com.builder.java/Dought.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Design Patterns/Builder/README.md b/Design Patterns/Builder/README.md index ca38a6a..d31712e 100644 --- a/Design Patterns/Builder/README.md +++ b/Design Patterns/Builder/README.md @@ -98,13 +98,13 @@ Uma forma de utilizar o padrão para a construção dessas Pizzas é como no exemplo abaixo: ``` java - Pizza sausagePizza = new PizzaBuilder(Size.SMALL, Dought.WHITE) + Pizza sausagePizza = new PizzaBuilder(Size.SMALL, Dought.WHITE_WHOLE_WHEAT) .withSauce(Sauce.RED) .withTopping(Topping.CHEESE, Topping.SAUSAGE, Topping.ONION) .withOlive() .build(); - Pizza cheesePizza = new PizzaBuilder(Size.LARGE, Dought.WHITE) + Pizza cheesePizza = new PizzaBuilder(Size.LARGE, Dought.WHITE_WHOLE_WHEAT) .withSauce(Sauce.WHITE) .withTopping(Topping.CHEESE) .build(); diff --git a/Design Patterns/Builder/com.builder.java/Dought.java b/Design Patterns/Builder/com.builder.java/Dought.java index 57778ce..368a3bf 100644 --- a/Design Patterns/Builder/com.builder.java/Dought.java +++ b/Design Patterns/Builder/com.builder.java/Dought.java @@ -1,3 +1,3 @@ enum Dought { - WHEAT, WHITE; + WHOLE_WHEAT, WHITE_WHOLE_WHEAT; }