设计模式笔记 ------ 建造者模式
无论是修一段路,或是盖一间房,就算是学习知识都是循序渐进的。先打基础,再做提高,最后成路、成房、成人。如果一上来就铺石子不打路基,直接砌墙不打房基,直接看书而不识字,想必一切都不会好吧。这其中就有了建造者模式的概念了。
建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者建造对象时,对客户端说来是透明的。而且,建造的顺序以及过程和建造材料都是固定的,这就保证了建造出来的产品不会缺这少那。
下面是建造者的类图
根据类图可以看出建造者的整个结构,分析如下
Builder:抽象建造者。它声明为创建一个Product对象的各个部件指定的抽象接口。
ConcreteBuilder:具体建造者。实现抽象接口,构建和装配各个部件。
Director:指挥者。构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象,它主要有两个作用,一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程。
Product:产品角色。一个具体的产品对象。
现在有个需求,很多人都在用中国移动的业务吧?中国移动曾经有两个套餐,神州行和动感地带。套餐中都有流量、短信、通话时长等。如何用建造者模式实现功能呢?
首先是产品类
//神州行套餐 public class ChinaMobilePackage { int price;// 价格 int flow;// 流量 int message;// 短信数 int callTime;// 通话时长 String name; public int getFlow() { return flow; } public void setFlow(int flow) { this.flow = flow; } public int getMessage() { return message; } public void setMessage(int message) { this.message = message; } public int getCallTime() { return callTime; } public void setCallTime(int callTime) { this.callTime = callTime; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } public void show() { System.out.println("中国移动" + name + "套餐包括:\n" + flow + "M流量、" + message + "条短信和" + callTime + "分钟通话时长。月使用费" + price + "元。"); } }
其次是建造接口
public interface ChinaMobilePackageBuilder { public void addName(); public void addFlow(); public void addMessage(); public void addCallTime(); public void addPrice(); public ChinaMobilePackage getResult(); }
各个建造的实现类
//神州行的建造者类 public class EasyOwnBuilder implements ChinaMobilePackageBuilder { private ChinaMobilePackage chinaMobilePackage = new ChinaMobilePackage(); @Override public void addName() { chinaMobilePackage.setName("神州行"); } @Override public void addFlow() { chinaMobilePackage.setFlow(30); } @Override public void addMessage() { chinaMobilePackage.setMessage(20); } @Override public void addCallTime() { chinaMobilePackage.setCallTime(300); } @Override public void addPrice() { chinaMobilePackage.setPrice(15); } @Override public ChinaMobilePackage getResult() { return chinaMobilePackage; } } //动感地带建造者类 public class MZoneBuilder implements ChinaMobilePackageBuilder { private ChinaMobilePackage chinaMobilePackage = new ChinaMobilePackage(); @Override public void addName() { chinaMobilePackage.setName("动感地带"); } @Override public void addFlow() { chinaMobilePackage.setFlow(500); } @Override public void addMessage() { chinaMobilePackage.setMessage(200); } @Override public void addCallTime() { chinaMobilePackage.setCallTime(30); } @Override public void addPrice() { chinaMobilePackage.setPrice(38); } @Override public ChinaMobilePackage getResult() { return chinaMobilePackage; } }
最后是导演类
public class Director { //指挥建筑过程,是有顺序区别的 public void construct(ChinaMobilePackageBuilder builder){ builder.addName(); builder.addCallTime(); builder.addFlow(); builder.addPrice(); builder.addMessage(); } }
客户端
public class POC { public static void main(String[] args) { Director director = new Director(); ChinaMobilePackageBuilder builder1 = new EasyOwnBuilder(); ChinaMobilePackageBuilder builder2 = new MZoneBuilder(); director.construct(builder1); ChinaMobilePackage product = builder1.getResult(); product.show(); director.construct(builder2); product = builder2.getResult(); product.show(); } }
建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用的模式。建造对象的过程会更加清晰,控制更加精确。创建对象时可以保证顺序和步骤不会变,产品便不会有结构上的缺失。客户端创建对象时,不必关系创建过程,对象的创建和表现分离,表示独立于过程,而且相同的建造过程也能获得不同的对象。
但是如果产品细节和组成部分差异较大,则不适合使用建造者模式。