|
| 1 | +--- |
| 2 | +shortTitle: Step Builder |
| 3 | +category: Creational |
| 4 | +language: de |
| 5 | +tag: |
| 6 | + - Code simplification |
| 7 | + - Domain |
| 8 | + - Encapsulation |
| 9 | + - Extensibility |
| 10 | + - Instantiation |
| 11 | + - Interface |
| 12 | +--- |
| 13 | + |
| 14 | +## Alternativbezeichnung |
| 15 | + |
| 16 | +* Fluent Builder |
| 17 | + |
| 18 | +## Zweck |
| 19 | + |
| 20 | +Das Step-Builder-Pattern ist eine erweiterte Technik, um komplexe Objekte übersichtlich und flexibel |
| 21 | +zu erzeugen. Es ist ideal für Szenarien, in denen die Objekterzeugung schrittweise und äußerst genau zu erfolgen hat. |
| 22 | + |
| 23 | +## Detaillierte Erklärung |
| 24 | + |
| 25 | +Vergleichsbeispiel: |
| 26 | + |
| 27 | +> Betrachten wir den Zusammenbau eines individuell konfigurierten Computers. |
| 28 | +Dafür sind mehrere Schritte nötig: Die CPU muss ausgewählt werden, ein Motherboard, dazu kommen |
| 29 | +Arbeitsspeicher, Grafikkarte und Festplatte, die nach und nach ins Gehäuse eingebaut werden müssen. |
| 30 | +Jeder Schritt folgt auf den anderen, bis schließlich ein funktionsfähiger Rechner entsteht. |
| 31 | +Dieser schrittweise Konstruktionsprozess entspricht dem Step-Builder-Pattern und sorgt dafür, |
| 32 | +dass alle nötigen Komponenten richtig zusammengebaut werden und anforderungsgemäß funktionieren. |
| 33 | + |
| 34 | +In einfachen Worten |
| 35 | + |
| 36 | +> Das Step-Builder-Pattern konstruiert komplexe Objekte nach und nach durch eine Reihe |
| 37 | +definierter Schritte. Das macht den Vorgang übersichtlich und flexibel. |
| 38 | + |
| 39 | +Wikipedia sagt |
| 40 | + |
| 41 | +> Step Builder ist eine Variante des Builder-Patterns mit dem Ziel, eine flexible Lösung |
| 42 | +zur schrittweisen Konstruktion komplexer Objekte anzubieten. Sie ist besonders hilfreich, |
| 43 | +wenn ein Objekt viele Initialisierungsschritte benötigt, die der Klarheit und Flexibilität wegen |
| 44 | +einzeln abgearbeitet werden können. |
| 45 | + |
| 46 | +Ablaufdiagramm |
| 47 | + |
| 48 | + |
| 49 | + |
| 50 | +## Programmbeispiel |
| 51 | + |
| 52 | +Als Erweiterung des Builder-Patterns führt Step Builder den Nutzer Schritt für Schritt durch |
| 53 | +den Erzeugungsprozess eines Objekts. Es werden immer nur die nächsten verfügbaren Schritte |
| 54 | +angezeigt, und die build-Methode ist erst dann verfügbar, wenn das Objekt tatsächlich bereit |
| 55 | +zum Bau ist. |
| 56 | + |
| 57 | +Betrachten wir eine Klasse `Character` mit vielen Attributen wie `name`, `fighterClass`, |
| 58 | +`wizardClass`, `weapon`, `spell`, und `abilities`. |
| 59 | + |
| 60 | +```java |
| 61 | +public class Character { |
| 62 | + |
| 63 | + private String name; |
| 64 | + private String fighterClass; |
| 65 | + private String wizardClass; |
| 66 | + private String weapon; |
| 67 | + private String spell; |
| 68 | + private List<String> abilities; |
| 69 | + |
| 70 | + public Character(String name) { |
| 71 | + this.name = name; |
| 72 | + } |
| 73 | + |
| 74 | +} |
| 75 | +``` |
| 76 | + |
| 77 | +Die Konstruktion ist wegen der vielen Attribute komplex. Darum verwenden wir Step Builder. |
| 78 | + |
| 79 | +Wir schreiben eine Klasse `CharacterStepBuilder`, um den Benutzer durch den Konstruktionsprozess zu führen. |
| 80 | + |
| 81 | +```java |
| 82 | +public class CharacterStepBuilder { |
| 83 | + |
| 84 | + // neuer Builder startet mit dem Schritt Namensvergabe |
| 85 | + public static NameStep newBuilder() { |
| 86 | + return new CharacterSteps(); |
| 87 | + } |
| 88 | + |
| 89 | +} |
| 90 | +``` |
| 91 | + |
| 92 | +Die Klasse `CharacterStepBuilder` enthält eine Reihe von Interfaces, |
| 93 | +die jeweils einen Schritt des Konstruktionsprozesses repräsentieren. Indem jedes Interface |
| 94 | +eine Methode für den folgenden Schritt deklariert, wird der Benutzer durch den Prozess geführt. |
| 95 | + |
| 96 | +```java |
| 97 | +// nach der Namensvergabe kommt die Auswahl der wizardClass oder fighterClass |
| 98 | +public interface NameStep { |
| 99 | + ClassStep name(String name); |
| 100 | +} |
| 101 | +``` |
| 102 | + |
| 103 | +```java |
| 104 | +// nach der Klassenwahl wird entweder eine Waffe oder ein Zauberspruch zugewiesen |
| 105 | +public interface ClassStep { |
| 106 | + WeaponStep fighterClass(String fighterClass); |
| 107 | + SpellStep wizardClass(String wizardClass); |
| 108 | +} |
| 109 | + |
| 110 | +// Weitere Schritte weggelassen |
| 111 | +``` |
| 112 | + |
| 113 | +Die Klasse `Steps` implementiert all diese Interfaces und baut schließlich das `Character`-Object. |
| 114 | + |
| 115 | +```java |
| 116 | +private static class Steps implements NameStep, ClassStep, WeaponStep, SpellStep, BuildStep { |
| 117 | + |
| 118 | + private String name; |
| 119 | + private String fighterClass; |
| 120 | + private String wizardClass; |
| 121 | + private String weapon; |
| 122 | + private String spell; |
| 123 | + private List<String> abilities; |
| 124 | + |
| 125 | + // Die Implementationen der Methoden für die einzelnen Schritte sind hier weggelassen |
| 126 | + |
| 127 | + @Override |
| 128 | + public Character build() { |
| 129 | + return new Character(name, fighterClass, wizardClass, weapon, spell, abilities); |
| 130 | + } |
| 131 | +} |
| 132 | +``` |
| 133 | + |
| 134 | +Jetzt ist die Erzeugung eines `Character`-Objekts ein geführter Prozess. |
| 135 | + |
| 136 | +```java |
| 137 | +public static void main(String[] args) { |
| 138 | + |
| 139 | + var warrior = CharacterStepBuilder |
| 140 | + .newBuilder() |
| 141 | + .name("Amberjill") |
| 142 | + .fighterClass("Paladin") |
| 143 | + .withWeapon("Sword") |
| 144 | + .noAbilities() |
| 145 | + .build(); |
| 146 | + |
| 147 | + LOGGER.info(warrior.toString()); |
| 148 | + |
| 149 | + var mage = CharacterStepBuilder |
| 150 | + .newBuilder() |
| 151 | + .name("Riobard") |
| 152 | + .wizardClass("Sorcerer") |
| 153 | + .withSpell("Fireball") |
| 154 | + .withAbility("Fire Aura") |
| 155 | + .withAbility("Teleport") |
| 156 | + .noMoreAbilities() |
| 157 | + .build(); |
| 158 | + |
| 159 | + LOGGER.info(mage.toString()); |
| 160 | + |
| 161 | + var thief = CharacterStepBuilder |
| 162 | + .newBuilder() |
| 163 | + .name("Desmond") |
| 164 | + .fighterClass("Rogue") |
| 165 | + .noWeapon() |
| 166 | + .build(); |
| 167 | + |
| 168 | + LOGGER.info(thief.toString()); |
| 169 | +} |
| 170 | +``` |
| 171 | + |
| 172 | +Konsolenausgabe: |
| 173 | + |
| 174 | +``` |
| 175 | +12:58:13.887 [main] INFO com.iluwatar.stepbuilder.App -- This is a Paladin named Amberjill armed with a Sword. |
| 176 | +12:58:13.889 [main] INFO com.iluwatar.stepbuilder.App -- This is a Sorcerer named Riobard armed with a Fireball and wielding [Fire Aura, Teleport] abilities. |
| 177 | +12:58:13.889 [main] INFO com.iluwatar.stepbuilder.App -- This is a Rogue named Desmond armed with a with nothing. |
| 178 | +``` |
| 179 | + |
| 180 | +## Verwendung |
| 181 | + |
| 182 | +* Wenn die Konstruktion eines Objekts viele Initialisierungsschritte benötigt. |
| 183 | +* Wenn die Objektkonstruktion komplex ist und viele Parameter enthält. |
| 184 | +* Um einen übersichtlichen, lesbaren und wartbaren Objekterzeugungsprozess bereitzustellen. |
| 185 | + |
| 186 | +## Tutorials |
| 187 | + |
| 188 | +* [Step Builder (Marco Castigliego)](http://rdafbn.blogspot.co.uk/2012/07/step-builder-pattern_28.html) |
| 189 | + |
| 190 | +## Reale Anwendungen in Java |
| 191 | +* Komplexe Konfigurationseinstellungen in Java-Anwendungen. |
| 192 | +* Konstruktion von Objekten für Datenbankeinträge mit vielen Feldern. |
| 193 | +* Konstruktion von GUI-Elementen, wo jeder Schritt einen anderen Teil der Schnittstelle festlegt. |
| 194 | + |
| 195 | +## Vor- und Nachteile |
| 196 | + |
| 197 | +Vorteile |
| 198 | + |
| 199 | +* Code wird lesbarer und wartbarer durch übersichtliche und prägnante Objektkonstruktion. |
| 200 | +* Erhöhte Flexibilität bei der Objekterzeugung durch Varianten im Konstruktionsprozess. |
| 201 | +* Unterstützt unveränderbare Objekte durch Abtrennung ihrer Erzeugung.ntation. |
| 202 | + |
| 203 | +Nachteile |
| 204 | + |
| 205 | +* Code kann durch zusätzliche Klassen und Interfaces komplexer werden. |
| 206 | +* Langatmiger Code bei vielen Konstruktionsschritten. |
| 207 | + |
| 208 | +## Verwandte Patterns |
| 209 | + |
| 210 | +* [Builder](https://java-design-patterns.com/patterns/builder/): Beide Patterns dienen der Konstruktion komplexer Objekte. Step Builder ist eine Variante mit Betonung auf schrittweisem Vorgehen. |
| 211 | +* [Fluent Interface](https://java-design-patterns.com/patterns/fluentinterface/): Wird oft zusammen mit Step Builder verwendet, um eine sprechende API mit Methodenverkettung zur Konstruktion bereitzustellen. |
| 212 | +* [Factory Method](https://java-design-patterns.com/patterns/factory-method/): Wird manchmal im Step-Builder-Pattern genutzt, um die Konstruktion des Builders selbst zu kapseln. |
| 213 | + |
| 214 | +## Quellen |
| 215 | + |
| 216 | +* [Clean Code: A Handbook of Agile Software Craftsmanship](https://amzn.to/3wRnjp5) |
| 217 | +* [Effective Java](https://amzn.to/4cGk2Jz) |
| 218 | +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3w0pvKI) |
0 commit comments