设计模式----建造者模式
为了介绍这个模式,我来举一个例子:KFC与大排档。
比如说香辣鸡腿堡,北京KFC的香辣鸡腿堡和南京的香辣鸡腿堡味道是差不多的,就算有差别差别也不会太大。
而大排档买的豆腐脑可能就不一样了,可能北方卖的豆腐脑是咸的,南方卖的豆腐脑是甜的,或者说这家卖的豆腐脑里面加酱油,那家豆腐脑里面加陈醋。
也就是说不同的饭馆,同一道菜做的口味可能天翻地别。
这是为什么呢,为什么KFC,麦当劳这样的快餐店卖的汉堡口味都差不多而大排档同一道菜口味不同的饭馆口味不同呢?
这就和他们的制作流程有关系。
KFC制作食物的整个流程都是固定的,如何加调料,油炸、烘焙的时间多长,都是有规定的。
然而大排档就不一样了,这家卖的鱼香肉丝有鱼香没肉丝,那家卖的鱼香肉丝有肉丝没鱼香,因为他们的制作工艺不同。
这个时候我们的建造者模式就是类似于KFC的模式。
我们先来看看UML类图:
先来看看商品类:
/** * @author 陈柏宇 * 产品类,由多个部件组成 */ public class Product { List<String> parts = new ArrayList<String>(); public void add(String part) { parts.add(part); } public void show() { System.out.println(); System.out.println("产品创建 ----"); for (String part : parts) { System.out.println(part); } } }
建造者类:
/** * @author 陈柏宇 * 建造者模式 * 封装了工艺所必需的流程 * * Builder是为了创建一个Product对象的各个部件指定的抽象接口。 */ public abstract class Builder { public abstract void BuildPartA(); public abstract void BuildPartB(); public abstract Product getResult(); }
具体建造者类:
class ConcreteBuilder1 extends Builder{ private Product product = new Product(); @Override public void BuildPartA() { product.add("部件A"); } @Override public void BuildPartB() { product.add("部件B"); } @Override public Product getResult() { return product; } }
class ConcreteBuilder2 extends Builder{ private Product product = new Product(); @Override public void BuildPartA() { product.add("部件X"); } @Override public void BuildPartB() { product.add("部件Y"); } @Override public Product getResult() { return product; } }
指挥者类:
/** * @author 陈柏宇 * 指挥者类,负责组件的组装 */ public class Director { public static void constructor(Builder builder) { builder.BuildPartA(); builder.BuildPartB(); } }
main函数:
public static void main(String[] args) { Builder builder1 = new ConcreteBuilder1(); Director.constructor(builder1); Product p1 = builder1.getResult(); p1.show(); Builder builder2 = new ConcreteBuilder1(); Director.constructor(builder2); Product p2 = builder1.getResult(); p2.show(); }
控制台输出:
产品创建 ---- 部件A 部件B 产品创建 ---- 部件A 部件B
我们再来看一个具体的例子:
KFC制作的例子,南京的KFC和淮安的KFC味道为什么如此相似?
产品类:
/** * @author 陈柏宇 * 产品类 */ public class Product { List<String> parts = new ArrayList<String>(); public void add(String part) { parts.add(part); } public void show() { System.out.println(); System.out.println("产品做好了:"); for (String part : parts) { System.out.println(part); } } }
KFC抽象接口类:
public abstract class KFC { public abstract void cook1(); public abstract void cook2(); public abstract Product getProduct(); }
淮安KFC具体实现类:
class HuaiAnKFC extends KFC{ private Product product = new Product(); @Override public void cook1() { product.add("放淮安的调料"); } @Override public void cook2() { product.add("用淮安的油炸"); } @Override public Product getProduct() { return product; } }
南京KFC具体实现类:
class NanJingKFC extends KFC{ private Product product = new Product(); @Override public void cook1() { product.add("放南京的调料"); } @Override public void cook2() { product.add("用南京的油炸"); } @Override public Product getProduct() { return product; } }
KFC工作人员类:
public class KFCCooker { public static void construct(KFC kfc) { kfc.cook1(); kfc.cook2(); } }
main函数:
public static void main(String[] args) { KFC kfc1 = new HuaiAnKFC(); KFCCooker.construct(kfc1); kfc1.getProduct().show(); KFC kfc2 = new NanJingKFC(); KFCCooker.construct(kfc2); kfc2.getProduct().show(); }
控制台输出:
产品做好了:
放淮安的调料
用淮安的油炸
产品做好了:
放南京的调料
用南京的油炸
这就是我用建造者模式解释为什么淮安的KFC口味和南京的KFC口味味道比较相似了。