Skip to content

Commit f52d7d3

Browse files
committed
iluwatar#111 Implementation of Step Builder pattern
1 parent 3dc6b81 commit f52d7d3

File tree

9 files changed

+541
-0
lines changed

9 files changed

+541
-0
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Creational design patterns abstract the instantiation process. They help make a
2727
* [Prototype](#prototype)
2828
* [Property](#property)
2929
* [Singleton](#singleton)
30+
* [Step Builder](#step-builder)
3031
* [Multiton](#multiton)
3132
* [Object Pool](#object-pool)
3233

@@ -181,6 +182,14 @@ A programming idiom is a means of expressing a recurring construct in one or mor
181182
**Real world examples:**
182183
* [java.lang.Runtime#getRuntime()](http://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#getRuntime%28%29)
183184

185+
## <a name="step-builder">Step Builder</a> [&#8593;](#list-of-design-patterns)
186+
**Intent:** An extension of the Builder pattern that fully guides the user through the creation of the object with no chances of confusion.
187+
The user experience will be much more improved by the fact that he will only see the next step methods available, NO build method until is the right time to build the object.
188+
189+
![alt text](./step-builder/etc/step-builder.png "Step Builder")
190+
191+
**Applicability:** Use the Step Builder pattern when the algorithm for creating a complex object should be independent of the parts that make up the object and how they're assembled the construction process must allow different representations for the object that's constructed when in the process of constructing the order is important.
192+
184193
## <a name="adapter">Adapter</a> [&#8593;](#list-of-design-patterns)
185194
**Intent:** Convert the interface of a class into another interface the clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.
186195

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
<module>async-method-invocation</module>
7474
<module>business-delegate</module>
7575
<module>half-sync-half-async</module>
76+
<module>step-builder</module>
7677
</modules>
7778

7879
<dependencyManagement>

step-builder/etc/step-builder.png

74.3 KB
Loading

step-builder/etc/step-builder.ucls

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<class-diagram version="1.1.8" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true"
3+
realizations="true" associations="true" dependencies="true" nesting-relationships="false">
4+
<interface id="1" language="java" name="com.iluwatar.stepbuilder.CharacterStepBuilder.SpellStep"
5+
project="step-builder" file="/step-builder/src/main/java/com/iluwatar/stepbuilder/CharacterStepBuilder.java"
6+
binary="false" corner="BOTTOM_RIGHT">
7+
<position height="-1" width="-1" x="301" y="280"/>
8+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
9+
sort-features="false" accessors="true" visibility="true">
10+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
11+
<operations public="true" package="true" protected="true" private="true" static="true"/>
12+
</display>
13+
</interface>
14+
<class id="2" language="java" name="com.iluwatar.stepbuilder.CharacterStepBuilder.CharacterSteps"
15+
project="step-builder" file="/step-builder/src/main/java/com/iluwatar/stepbuilder/CharacterStepBuilder.java"
16+
binary="false" corner="BOTTOM_RIGHT">
17+
<position height="-1" width="-1" x="95" y="345"/>
18+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
19+
sort-features="false" accessors="true" visibility="true">
20+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
21+
<operations public="true" package="true" protected="true" private="true" static="true"/>
22+
</display>
23+
</class>
24+
<class id="3" language="java" name="com.iluwatar.stepbuilder.CharacterStepBuilder" project="step-builder"
25+
file="/step-builder/src/main/java/com/iluwatar/stepbuilder/CharacterStepBuilder.java" binary="false"
26+
corner="BOTTOM_RIGHT">
27+
<position height="-1" width="-1" x="92" y="56"/>
28+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
29+
sort-features="false" accessors="true" visibility="true">
30+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
31+
<operations public="true" package="true" protected="true" private="true" static="true"/>
32+
</display>
33+
</class>
34+
<interface id="4" language="java" name="com.iluwatar.stepbuilder.CharacterStepBuilder.AbilityStep"
35+
project="step-builder" file="/step-builder/src/main/java/com/iluwatar/stepbuilder/CharacterStepBuilder.java"
36+
binary="false" corner="BOTTOM_RIGHT">
37+
<position height="-1" width="-1" x="409" y="418"/>
38+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
39+
sort-features="false" accessors="true" visibility="true">
40+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
41+
<operations public="true" package="true" protected="true" private="true" static="true"/>
42+
</display>
43+
</interface>
44+
<interface id="5" language="java" name="com.iluwatar.stepbuilder.CharacterStepBuilder.ClassStep"
45+
project="step-builder" file="/step-builder/src/main/java/com/iluwatar/stepbuilder/CharacterStepBuilder.java"
46+
binary="false" corner="BOTTOM_RIGHT">
47+
<position height="-1" width="-1" x="406" y="163"/>
48+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
49+
sort-features="false" accessors="true" visibility="true">
50+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
51+
<operations public="true" package="true" protected="true" private="true" static="true"/>
52+
</display>
53+
</interface>
54+
<interface id="6" language="java" name="com.iluwatar.stepbuilder.CharacterStepBuilder.WeaponStep"
55+
project="step-builder" file="/step-builder/src/main/java/com/iluwatar/stepbuilder/CharacterStepBuilder.java"
56+
binary="false" corner="BOTTOM_RIGHT">
57+
<position height="-1" width="-1" x="509" y="279"/>
58+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
59+
sort-features="false" accessors="true" visibility="true">
60+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
61+
<operations public="true" package="true" protected="true" private="true" static="true"/>
62+
</display>
63+
</interface>
64+
<interface id="7" language="java" name="com.iluwatar.stepbuilder.CharacterStepBuilder.NameStep" project="step-builder"
65+
file="/step-builder/src/main/java/com/iluwatar/stepbuilder/CharacterStepBuilder.java" binary="false"
66+
corner="BOTTOM_RIGHT">
67+
<position height="-1" width="-1" x="404" y="49"/>
68+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
69+
sort-features="false" accessors="true" visibility="true">
70+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
71+
<operations public="true" package="true" protected="true" private="true" static="true"/>
72+
</display>
73+
</interface>
74+
<interface id="8" language="java" name="com.iluwatar.stepbuilder.CharacterStepBuilder.BuildStep"
75+
project="step-builder" file="/step-builder/src/main/java/com/iluwatar/stepbuilder/CharacterStepBuilder.java"
76+
binary="false" corner="BOTTOM_RIGHT">
77+
<position height="-1" width="-1" x="412" y="550"/>
78+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
79+
sort-features="false" accessors="true" visibility="true">
80+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
81+
<operations public="true" package="true" protected="true" private="true" static="true"/>
82+
</display>
83+
</interface>
84+
<class id="9" language="java" name="com.iluwatar.stepbuilder.Character" project="step-builder"
85+
file="/step-builder/src/main/java/com/iluwatar/stepbuilder/Character.java" binary="false" corner="BOTTOM_RIGHT">
86+
<position height="-1" width="-1" x="710" y="217"/>
87+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
88+
sort-features="false" accessors="true" visibility="true">
89+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
90+
<operations public="true" package="true" protected="true" private="true" static="true"/>
91+
</display>
92+
</class>
93+
<realization id="10">
94+
<bendpoint x="252" y="168"/>
95+
<end type="SOURCE" refId="2"/>
96+
<end type="TARGET" refId="5"/>
97+
</realization>
98+
<realization id="11">
99+
<bendpoint x="255" y="419"/>
100+
<end type="SOURCE" refId="2"/>
101+
<end type="TARGET" refId="4"/>
102+
</realization>
103+
<realization id="12">
104+
<bendpoint x="197" y="123"/>
105+
<end type="SOURCE" refId="2"/>
106+
<end type="TARGET" refId="7"/>
107+
</realization>
108+
<dependency id="13">
109+
<end type="SOURCE" refId="3"/>
110+
<end type="TARGET" refId="7"/>
111+
</dependency>
112+
<dependency id="14">
113+
<end type="SOURCE" refId="5"/>
114+
<end type="TARGET" refId="1"/>
115+
</dependency>
116+
<realization id="15">
117+
<bendpoint x="398" y="346"/>
118+
<end type="SOURCE" refId="2"/>
119+
<end type="TARGET" refId="6"/>
120+
</realization>
121+
<dependency id="16">
122+
<end type="SOURCE" refId="7"/>
123+
<end type="TARGET" refId="5"/>
124+
</dependency>
125+
<realization id="17">
126+
<bendpoint x="261" y="554"/>
127+
<end type="SOURCE" refId="2"/>
128+
<end type="TARGET" refId="8"/>
129+
</realization>
130+
<dependency id="18">
131+
<end type="SOURCE" refId="3"/>
132+
<end type="TARGET" refId="2"/>
133+
</dependency>
134+
<dependency id="19">
135+
<end type="SOURCE" refId="1"/>
136+
<end type="TARGET" refId="4"/>
137+
</dependency>
138+
<dependency id="20">
139+
<bendpoint x="512" y="477"/>
140+
<end type="SOURCE" refId="6"/>
141+
<end type="TARGET" refId="8"/>
142+
</dependency>
143+
<dependency id="21">
144+
<end type="SOURCE" refId="4"/>
145+
<end type="TARGET" refId="8"/>
146+
</dependency>
147+
<realization id="22">
148+
<end type="SOURCE" refId="2"/>
149+
<end type="TARGET" refId="1"/>
150+
</realization>
151+
<dependency id="23">
152+
<bendpoint x="597" y="547"/>
153+
<end type="SOURCE" refId="8"/>
154+
<end type="TARGET" refId="9"/>
155+
</dependency>
156+
<dependency id="24">
157+
<bendpoint x="97" y="602"/>
158+
<bendpoint x="712" y="596"/>
159+
<end type="SOURCE" refId="2"/>
160+
<end type="TARGET" refId="9"/>
161+
</dependency>
162+
<dependency id="25">
163+
<end type="SOURCE" refId="5"/>
164+
<end type="TARGET" refId="6"/>
165+
</dependency>
166+
<dependency id="26">
167+
<end type="SOURCE" refId="6"/>
168+
<end type="TARGET" refId="4"/>
169+
</dependency>
170+
<dependency id="27">
171+
<bendpoint x="303" y="475"/>
172+
<end type="SOURCE" refId="1"/>
173+
<end type="TARGET" refId="8"/>
174+
</dependency>
175+
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
176+
sort-features="false" accessors="true" visibility="true">
177+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
178+
<operations public="true" package="true" protected="true" private="true" static="true"/>
179+
</classifier-display>
180+
<association-display labels="true" multiplicity="true"/>
181+
</class-diagram>

step-builder/pom.xml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<artifactId>java-design-patterns</artifactId>
8+
<groupId>com.iluwatar</groupId>
9+
<version>1.5.0</version>
10+
</parent>
11+
<artifactId>step-builder</artifactId>
12+
<dependencies>
13+
<dependency>
14+
<groupId>junit</groupId>
15+
<artifactId>junit</artifactId>
16+
<scope>test</scope>
17+
</dependency>
18+
</dependencies>
19+
</project>
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.iluwatar.stepbuilder;
2+
3+
/**
4+
* Step Builder Pattern
5+
*
6+
* <p><b>Intent</b>
7+
* <br/>
8+
* An extension of the Builder pattern that fully guides the user
9+
* through the creation of the object with no chances of confusion.
10+
* <br/>
11+
* The user experience will be much more improved by the fact that
12+
* he will only see the next step methods available, NO build method
13+
* until is the right time to build the object.
14+
*
15+
* <p><b>Implementation</b>
16+
* </br>
17+
* <ul>The concept is simple:
18+
*
19+
* <li>Write creational steps inner classes or interfaces where each
20+
* method knows what can be displayed next.</li>
21+
*
22+
* <li>Implement all your steps interfaces in an inner static class.</li>
23+
*
24+
* <li>Last step is the BuildStep, in charge of creating the object
25+
* you need to build.</li>
26+
* </ul>
27+
*
28+
* <p><b>Applicability</b>
29+
* <br/>
30+
* Use the Step Builder pattern when the algorithm for creating a
31+
* complex object should be independent of the parts that make up
32+
* the object and how they're assembled the construction process must
33+
* allow different representations for the object that's constructed
34+
* when in the process of constructing the order is important.
35+
*
36+
* http://rdafbn.blogspot.co.uk/2012/07/step-builder-pattern_28.html
37+
*/
38+
public class App {
39+
public static void main(String[] args) {
40+
41+
Character warrior = CharacterStepBuilder.newBuilder()
42+
.name("Amberjill")
43+
.fighterClass("Paladin")
44+
.withWeapon("Sword")
45+
.noAbilities()
46+
.build();
47+
48+
System.out.println(warrior);
49+
50+
Character mage = CharacterStepBuilder.newBuilder()
51+
.name("Riobard")
52+
.wizardClass("Sorcerer")
53+
.withSpell("Fireball")
54+
.withAbility("Fire Aura")
55+
.withAbility("Teleport")
56+
.noMoreAbilities()
57+
.build();
58+
59+
System.out.println(mage);
60+
61+
Character thief = CharacterStepBuilder.newBuilder()
62+
.name("Desmond")
63+
.fighterClass("Rogue")
64+
.noWeapon()
65+
.build();
66+
67+
System.out.println(thief);
68+
}
69+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.iluwatar.stepbuilder;
2+
3+
import java.util.List;
4+
5+
/**
6+
* The class with many parameters.
7+
*/
8+
public class Character {
9+
10+
private String name;
11+
private String fighterClass;
12+
private String wizardClass;
13+
private String weapon;
14+
private String spell;
15+
private List<String> abilities;
16+
17+
public Character(String name) {
18+
this.name = name;
19+
}
20+
21+
public String getName() {
22+
return name;
23+
}
24+
25+
public void setName(String name) {
26+
this.name = name;
27+
}
28+
29+
public String getFighterClass() {
30+
return fighterClass;
31+
}
32+
33+
public void setFighterClass(String fighterClass) {
34+
this.fighterClass = fighterClass;
35+
}
36+
37+
public String getWizardClass() {
38+
return wizardClass;
39+
}
40+
41+
public void setWizardClass(String wizardClass) {
42+
this.wizardClass = wizardClass;
43+
}
44+
45+
public String getWeapon() {
46+
return weapon;
47+
}
48+
49+
public void setWeapon(String weapon) {
50+
this.weapon = weapon;
51+
}
52+
53+
public String getSpell() {
54+
return spell;
55+
}
56+
57+
public void setSpell(String spell) {
58+
this.spell = spell;
59+
}
60+
61+
public List<String> getAbilities() {
62+
return abilities;
63+
}
64+
65+
public void setAbilities(List<String> abilities) {
66+
this.abilities = abilities;
67+
}
68+
69+
@Override
70+
public String toString() {
71+
StringBuilder sb = new StringBuilder();
72+
sb.append("This is a ");
73+
sb.append(fighterClass != null ? fighterClass : wizardClass);
74+
sb.append(" named a ");
75+
sb.append(name);
76+
sb.append(" armed ");
77+
sb.append(weapon != null ? weapon : spell != null ? spell : "with nothing");
78+
sb.append(abilities != null ? (" and wielding " + abilities + " abilities") : "");
79+
sb.append(".");
80+
return sb.toString();
81+
}
82+
}

0 commit comments

Comments
 (0)