1 Übersicht
Builder Pattern (Builder Pattern) wird hauptsächlich verwendet, um „ein komplexes Objekt Schritt für Schritt zu erstellen“, wobei „Schritt für Schritt“ ein stabiler Algorithmus ist, während sich die verschiedenen Teile des komplexen Objekts häufig ändern. Daher wird das Builder-Muster hauptsächlich zur Lösung der sich ändernden Anforderungen des „Objektteils“ verwendet. Dies ermöglicht eine detailliertere Kontrolle über den Objektkonstruktionsprozess.
2 Beispiel
Nehmen Sie als Beispiel die Herstellung von Mobiltelefonen. Jedes Mobiltelefon ist in Bildschirm, CPU und Akku unterteilt. Derzeit werden zwei Arten von Mobiltelefonen hergestellt: Apple und Samsung.
Apfel:
package org.scott.builder.before.use; import java.util.ArrayList; import java.util.List; /** * @author Scott * @version 2013-11-20 * @description */ public class ApplePhone { List<String> parts = new ArrayList<String>(); public void createCPU() { parts.add("CUP: Qualcomm"); } public void createScreen() { parts.add("SCREEN: JDI"); } public void createBattery() { parts.add("BATTERY: DeSai"); } public void show(){ System.out.print("产品部件信息:"); for(String part : parts){ System.out.print(part + "\t"); } } }
Samsung:
package org.scott.builder.before.use; import java.util.ArrayList; import java.util.List; /** * @author Scott * @version 2013-11-20 * @description */ public class SamsungPhone { List<String> parts = new ArrayList<String>(); public void createCPU() { parts.add("CUP: MTK"); } public void createScreen() { parts.add("SCREEN: Samsung"); } public void createBattery() { parts.add("BATTERY: DeSai"); } public void show(){ System.out.print("产品部件信息:"); for(String part : parts){ System.out.print(part + "\t"); } } }
Testkunde:
package org.scott.builder.before.use; /** * @author Scott * @version 2013-11-20 * @description */ public class BuilerTest { private static ApplePhone iphone = new ApplePhone(); private static SamsungPhone samPhone = new SamsungPhone(); public static void main(String args[]){ iphone.createCPU(); iphone.createScreen(); iphone.createBattery(); iphone.show(); samPhone.createCPU(); samPhone.createScreen(); samPhone.createBattery(); samPhone.show(); } }
Haben Sie ein Problem gefunden? Das heißt, jeder Prozess zur Herstellung von Mobiltelefonen ist derselbe, aber die spezifische Verarbeitung jedes Prozesses ist unterschiedlich. Es gibt nur wenige Schritte Verarbeitung der einzelnen Prozessänderungen, daraus können wir das Unveränderliche, „Unveränderte, um allen Änderungen gerecht zu werden“, extrahieren und das Veränderliche auf bestimmte Produkte übertragen.
Wie geht das konkret? Diesmal ist der Builder-Modus praktisch.
Werfen wir zunächst einen Blick auf die Telefonoberfläche:
package org.scott.builder.after.use; import java.util.ArrayList; import java.util.List; /** * @author Scott * @version 2013-11-20 * @description */ public abstract class Phone { protected List<String> parts = new ArrayList<String>(); public void add(String part){ parts.add(part); } public void show(){ System.out.print("产品部件信息:"); for(String part : parts){ System.out.print(part + "\t"); } } }
Apple-Handykategorie:
package org.scott.builder.after.use; /** * @author Scott * @version 2013-11-20 * @description */ public class ApplePhone extends Phone{ }
Samsung-Handykategorie:
package org.scott.builder.after.use; /** * @author Scott * @version 2013-11-20 * @description */ public class SamsungPhone extends Phone{ }
Definieren Sie dann einen Interface Builder für den Produktionsschritt:
package org.scott.builder.after.use; /** * @author Scott * @version 2013-11-20 * @description */ public interface Builder { public void buildCPU(); public void buildScreen(); public void buildBattery(); public Phone getPhone(); }
Builder für iPhone:
package org.scott.builder.after.use; /** * @author Scott * @version 2013-11-20 * @description */ public class ApplePhoneBuilder implements Builder{ private Phone phone = new ApplePhone(); @Override public void buildCPU() { phone.add("CUP: Qualcomm"); } @Override public void buildScreen() { phone.add("SCREEN: JDI"); } @Override public void buildBattery() { phone.add("BATTERY: DeSai"); } @Override public Phone getPhone() { return phone; } }
Builder für Samsung-Handys:
package org.scott.builder.after.use; /** * @author Scott * @version 2013-11-20 * @description */ public class SamsungPhoneBuilder implements Builder{ private Phone phone = new SamsungPhone(); @Override public void buildCPU() { phone.add("CUP: MTK"); } @Override public void buildScreen() { phone.add("SCREEN: Samsung"); } @Override public void buildBattery() { phone.add("BATTERY: DeSai"); } @Override public Phone getPhone() { return phone; } }
Direktor, der die spezifische Produktion von Mobiltelefonen leitet:
package org.scott.builder.after.use; /** * @author Scott * @version 2013-11-20 * @description */ public class Director { private Builder builder; public Director(Builder builder){ this.builder = builder; } public void construct(){ builder.buildCPU(); builder.buildScreen(); builder.buildBattery(); } }
Schreiben Sie abschließend eine Testklasse:
package org.scott.builder.after.use; /** * @author Scott * @version 2013-11-20 * @description */ public class BuilderTest { private static Builder iPhoneBuilder = new ApplePhoneBuilder(); private static Builder samPhoneBuilder = new SamsungPhoneBuilder(); public static void main(String[] args) { Director director = new Director(iPhoneBuilder); director.construct(); Phone phone = iPhoneBuilder.getPhone(); System.out.println("iphone"); phone.show(); director = new Director(samPhoneBuilder); director.construct(); phone = samPhoneBuilder.getPhone(); System.out.println("\nsamSung"); phone.show(); } }
Laufergebnisse:
iphone 产品部件信息:CUP: Qualcomm SCREEN: JDI BATTERY: DeSai samSung 产品部件信息:CUP: MTK SCREEN: Samsung BATTERY: DeSai
Die beiden Phone-Entitätsklassen sind hier leer. Wenn dies der Fall ist, können sie weggelassen werden. Wenn die Phone-Schnittstelle auch weggelassen werden kann, bleiben am Ende nur die Director-, Builder- und bestimmte Bulider-Implementierungsklassen übrig. Darüber hinaus sind die Klassen „ApplePhone“ und „SamsungPhone“ zwei unterschiedliche Mobiltelefonmarken Wie kann also der Rückgabewert der in der Builder-Schnittstelle angegebenen Methode getPhone () ermittelt werden?
Unabhängig davon, ob der Rückgabewerttyp ApplePhone oder SamsungPhone ist, treten Probleme auf, da die Typen der zurückgegebenen Ergebnisse nicht einheitlich sind. Zu diesem Zeitpunkt können Sie Phone als leere Schnittstelle definieren (eine Schnittstelle, die keine Methoden enthält) und dann diese spezifischen Produktklassen, die keine Beziehung zueinander haben, diese Schnittstelle implementieren lassen. Dann ist der Rückgabewerttyp von getPhone(. )-Methode, die in der Builder-Schnittstelle angegeben ist. Es handelt sich immer noch um einen Telefontyp, der das Problem löst. In diesem Fall ist es jedoch nicht erforderlich, den Builder-Modus zu verwenden.
Weitere Artikel zum Erlernen des Builder-Musters von Java-Designmustern finden Sie auf der chinesischen PHP-Website!