1 Présentation
Builder Pattern (Builder Pattern) est principalement utilisé pour « construire un objet complexe étape par étape », dans lequel « étape par étape » est un algorithme stable, tandis que les différentes parties de l'objet complexe changent fréquemment. Par conséquent, le modèle de construction est principalement utilisé pour résoudre les exigences changeantes de la « partie objet ». Cela permet un contrôle plus fin du processus de construction d’objets.
2 Exemple
Prenons l'exemple de la production de téléphones mobiles. Chaque téléphone mobile est divisé en écran, CPU et batterie. Il existe désormais deux types de téléphones mobiles à produire, Apple et Samsung.
Pomme :
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"); } } }
Client test :
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(); } }
Avez-vous trouvé un problème ? Autrement dit, chaque processus de production de téléphones mobiles est le même. Pour être précis, les noms des processus sont les mêmes, mais le traitement spécifique de chaque processus est différent. Il n'y a que quelques étapes spécifiques. le traitement de chaque changement de processus, à partir de là, nous pouvons extraire l'immuable, "inchangé pour faire face à tous les changements", et transmettre la modification à des produits spécifiques.
Comment le faire spécifiquement ? Cette fois, le mode Builder est pratique.
Jetons d’abord un coup d’œil à l’interface du téléphone :
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"); } } }
Catégorie de téléphone mobile Apple :
package org.scott.builder.after.use; /** * @author Scott * @version 2013-11-20 * @description */ public class ApplePhone extends Phone{ }
Catégorie de téléphone mobile Samsung :
package org.scott.builder.after.use; /** * @author Scott * @version 2013-11-20 * @description */ public class SamsungPhone extends Phone{ }
Définissez ensuite un Interface Builder pour l'étape de production :
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(); }
Constructeur pour 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; } }
Constructeur pour téléphones mobiles Samsung :
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; } }
Directeur qui guide la production spécifique des téléphones portables :
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(); } }
Enfin, écrivez une classe de test :
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(); } }
Résultats en cours d'exécution :
iphone 产品部件信息:CUP: Qualcomm SCREEN: JDI BATTERY: DeSai samSung 产品部件信息:CUP: MTK SCREEN: Samsung BATTERY: DeSai
Les deux classes d'entité Phone ici sont vides. Si tel est le cas, alors elles peuvent être omises. Si l'interface Phone peut également être omise, à la fin, seules les classes d'implémentation Director, Builder et Bulider spécifiques seront laissées. De plus, la classe ApplePhone et la classe SamsungPhone sont deux classes liées. Ce sont des marques de téléphones mobiles différentes. Si vous rencontrez deux classes ou plus qui ne sont pas très liées, il n'est pas nécessaire que l'interface publique Phone existe. , Alors comment déterminer la valeur de retour de la méthode getPhone() spécifiée dans l'interface Builder ?
Que le type de valeur renvoyée soit ApplePhone ou SamsungPhone, des problèmes surviendront car le type du résultat renvoyé n'est pas uniforme. À ce stade, vous pouvez définir Phone comme une interface vide (une interface qui ne contient aucune méthode), puis laisser ces classes de produits spécifiques qui n'ont aucune relation les unes avec les autres implémenter cette interface, puis le type de valeur de retour de getPhone(. ) méthode spécifiée dans l'interface Builder. C'est toujours un type Phone, qui résout le problème. Cependant, dans ce cas, il n’est pas nécessaire d’utiliser le mode Builder.
Pour plus d'articles liés à l'apprentissage du modèle de construction des modèles de conception Java, veuillez faire attention au site Web PHP chinois !