Skip to content

Commit a95bd31

Browse files
committed
Merge pull request iluwatar#194 from dmitz/step-builder
iluwatar#111 Implementation of Step Builder pattern
2 parents c18f720 + 0beb194 commit a95bd31

File tree

9 files changed

+542
-0
lines changed

9 files changed

+542
-0
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ system independent of how its objects are created, composed, and represented.
3232
* [Prototype](#prototype)
3333
* [Property](#property)
3434
* [Singleton](#singleton)
35+
* [Step Builder](#step-builder)
3536
* [Multiton](#multiton)
3637
* [Object Pool](#object-pool)
3738

@@ -206,6 +207,14 @@ access to it.
206207
**Real world examples:**
207208
* [java.lang.Runtime#getRuntime()](http://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#getRuntime%28%29)
208209

210+
## <a name="step-builder">Step Builder</a> [&#8593;](#list-of-design-patterns)
211+
**Intent:** An extension of the Builder pattern that fully guides the user through the creation of the object with no chances of confusion.
212+
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.
213+
214+
![alt text](./step-builder/etc/step-builder.png "Step Builder")
215+
216+
**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.
217+
209218
## <a name="adapter">Adapter</a> [&#8593;](#list-of-design-patterns)
210219
**Intent:** Convert the interface of a class into another interface the clients
211220
expect. Adapter lets classes work together that couldn't otherwise because of
@@ -1008,6 +1017,7 @@ other words, version numbers are used only for project planning sake.
10081017
* [Patterns of Enterprise Application Architecture](http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420)
10091018
* [Spring Data](http://www.amazon.com/Spring-Data-Mark-Pollack/dp/1449323952/ref=sr_1_1)
10101019
* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2)
1020+
* [Marco Castigliego - Step Builder](http://rdafbn.blogspot.co.uk/2012/07/step-builder-pattern_28.html)
10111021

10121022

10131023
# License

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 ");
75+
sb.append(name);
76+
sb.append(" armed with a ");
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)