一、建造者模式
-
属于创建型模式,builder。
-
建造者模式主要用于在创建复杂对象时的一种模式。
-
复杂对象场景之一:线程池对象。如下构造方法,参数的类型比较复杂,相互搭配使用可以创建不同种类的线程池。
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
-
场景二:可变字符串,StringBuffer,StringBuilder,提供了很多对当前对象的内容进行修改的方法,返回依然是本对象,反映出对象的操作比较复杂。该API的设计模式就是建造者模式。
二、建造者模式的主要设计要素(以 StringBuilder 为例)
- 产品要素,CharSequence 接口
- 抽象建造者,Appendable 接口是基础
- 具体建造者,AbstractStringBuilder 抽象类
- 指挥者,领导者,StringBuilder 类
三、建造者模式的一般化设计
-
快餐店做快餐,约定每份快餐由两部分组成,一个是饭食,另一个是饮料,对于饭食采用纸盒包装,饮料采用瓶子包装,饭食又分为蛋炒饭,鱼焖饭……饮料又分为茶,咖啡……。不同的饭食和饮料都有不同的价格。可以按套餐售出,也可以按单品售出。
-
把以上产品图用面向对象的思路来进行描绘,首先要想到哪些成分今后是会进行扩展的(变化),凡是可能要扩展的内容都应该进行抽象化处理。抽象化就是把一些共同的特征和行为定义成一个接口或抽象类,然后再考虑使用哪些实现类(考虑当下的产品内容)。
-
package com.zhong.test_10; public interface Item {//产品的模型 String name();//名字 Packing packing();//采用的包装 double price();//价格 }
package com.zhong.test_10; public interface Packing {//包装 String pack(); }
package com.zhong.test_10; public class PaperBox implements Packing { @Override public String pack() { return "纸盒"; } }
package com.zhong.test_10; public class BottleBox implements Packing { @Override public String pack() { return "瓶子"; } }
package com.zhong.test_10; public abstract class Rice implements Item {//饭食,为抽象类 @Override public Packing packing() { return new PaperBox(); } }
package com.zhong.test_10; public class EggRice extends Rice { @Override public String name() { return "蛋炒饭"; } @Override public double price() { return 12; } }
package com.zhong.test_10; public class FishRice extends Rice { @Override public String name() { return "鱼焖饭"; } @Override public double price() { return 15; } }
package com.zhong.test_10; public abstract class Drink implements Item {//饮料同理 @Override public Packing packing() { return new BottleBox(); } }
package com.zhong.test_10; public class TeaDrink extends Drink { @Override public String name() { return "茶"; } @Override public double price() { return 9; } }
package com.zhong.test_10; public class CoffeeDrink extends Drink { @Override public String name() { return "咖啡"; } @Override public double price() { return 15; } }
package com.zhong.test_10; import java.util.ArrayList; public class Meal {//套餐的模型 private ArrayList<Item> items = new ArrayList<>(); public Meal addItem(Item item) {//明显体现出建造者模式特征,为链式方法 items.add(item); return this; } public void showItems() { double totalCost = 0.0; for (Item item : items) { System.out.println("名称:" + item.name() + ",包装:" + item.packing().pack() + ",价格:" + item.price()); totalCost += item.price(); } System.out.println("总价:" + totalCost); } }
package com.zhong.test_10; public class MealDirector {//管理者 public Meal buildA() { Meal meal = new Meal(); meal.addItem(new EggRice()).addItem(new TeaDrink()); return meal; } public Meal buildB() { Meal meal = new Meal(); meal.addItem(new EggRice()).addItem(new CoffeeDrink()); return meal; } public Meal buildC() { Meal meal = new Meal(); meal.addItem(new FishRice()).addItem(new TeaDrink()); return meal; } public Meal buildD() { Meal meal = new Meal(); meal.addItem(new FishRice()).addItem(new CoffeeDrink()); return meal; } public static void main(String[] args) { MealDirector mealDirector = new MealDirector(); Meal mealA = mealDirector.buildA(); Meal mealB = mealDirector.buildB(); Meal mealC = mealDirector.buildC(); Meal mealD = mealDirector.buildD(); mealA.showItems(); mealB.showItems(); mealC.showItems(); mealD.showItems(); } }