建造者模式
建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
个人感觉好深奥的样子,别急,我们举一个简答的例子来介绍什么是建造者模式。
建造者模式好比建楼房,基本的流程不变如先设计图纸,测量地形,打地基等等(我不是学建筑的,不是太清楚这个,反正大致就是这个意思),但是其中的细节却是变化的,比如设计的图纸不同。建造者模式可以保证了流程不会变化,既不会增加,也不会减少或者次序发生变化。嗯,大概就是这个意思,如果还是不明白也没事儿,通过看下面的例子进一步理解。
建造者模式通常包含下面四个部分:
Product:要创建的复杂对象。
Director:导演类,指定了要创建一个复杂对象的流程,即指定了复杂对象各个组成部分的创建顺序。
Builder:是一个抽象的接口,指定了要创建复杂对象的哪些部分,但不做具体实现。
ConcreteBuilder:继承Builder,用于复杂对象各个部分的具体实现。
下面是例子:
我国明清时期科举考试中有一种八股文,考生要严格按照八股,即破题、承题、起讲、入题、起股、中股、后股、束股来写文章,我们把八股文看做一个要创建的复杂对象,它有八部分组成,这八个部分的创建顺序是稳定的,但各个构建自身存在很大的变化,因为每个人写的文章都不会相同,下面我们试着用代码实现:
//产品---八股文 class Product{ private String poTi; //破题 private String chengTi; //承题 private String qiJiang; //起讲 private String ruTi; //入题 private String qiGu; //起股 private String zhongGu; //中股 private String houGu; //后股 private String shuGu; //束股 public String getPoTi() { return poTi; } public void setPoTi(String poTi) { System.out.println("写破题部分"); this.poTi = poTi; } public String getChengTi() { return chengTi; } public void setChengTi(String chengTi) { System.out.println("写承题部分"); this.chengTi = chengTi; } public String getQiJiang() { return qiJiang; } public void setQiJiang(String qiJiang) { System.out.println("写起讲部分"); this.qiJiang = qiJiang; } public String getRuTi() { return ruTi; } public void setRuTi(String ruTi) { System.out.println("写入题部分"); this.ruTi = ruTi; } public String getQiGu() { return qiGu; } public void setQiGu(String qiGu) { System.out.println("写起股部分"); this.qiGu = qiGu; } public String getZhongGu() { return zhongGu; } public void setZhongGu(String zhongGu) { System.out.println("写中股部分"); this.zhongGu = zhongGu; } public String getHouGu() { return houGu; } public void setHouGu(String houGu) { System.out.println("写后股部分"); this.houGu = houGu; } public String getShuGu() { return shuGu; } public void setShuGu(String shuGu) { System.out.println("写束股部分"); this.shuGu = shuGu; } public String toString(){ return poTi+""+chengTi+""+qiJiang+""+ruTi+""+qiGu+""+zhongGu+""+houGu+""+shuGu; } } //抽象的Builder abstract class Builder{ public abstract void buildPoTi(); public abstract void buildChengTi(); public abstract void buildQiJiang(); public abstract void buildRuTi(); public abstract void buildQiGu(); public abstract void buildZhongGu(); public abstract void buildHouGU(); public abstract void buildShuGu(); public abstract Product getProduct(); } //建造者--写文章的人 class ConcreteBuilder extends Builder{ private Product product = new Product(); public void buildPoTi() { product.setPoTi("破题 "); } public void buildChengTi() { product.setChengTi("承题 "); } public void buildQiJiang() { product.setQiJiang("起讲 "); } public void buildRuTi() { product.setRuTi("入题 "); } public void buildQiGu() { product.setQiGu("起股 "); } public void buildZhongGu() { product.setZhongGu("中股 "); } public void buildHouGU() { product.setHouGu("后股 "); } public void buildShuGu() { product.setShuGu("束股 "); } public Product getProduct(){ return product; } } //建造者2--写文章的人 class ConcreteBuilder2 extends Builder{ private Product product = new Product(); public void buildPoTi() { product.setPoTi("破题2 "); } public void buildChengTi() { product.setChengTi("承题2 "); } public void buildQiJiang() { product.setQiJiang("起讲2 "); } public void buildRuTi() { product.setRuTi("入题2"); } public void buildQiGu() { product.setQiGu("起股2"); } public void buildZhongGu() { product.setZhongGu("中股2 "); } public void buildHouGU() { product.setHouGu("后股2 "); } public void buildShuGu() { product.setShuGu("束股2 "); } public Product getProduct(){ return product; } } //导演类,负责规范流程--即规定八股文的格式 class Director{ private Builder concreteBuilder; public Director(Builder concreteBuilder){ this.concreteBuilder = concreteBuilder; } public void construct(){ concreteBuilder.buildPoTi(); //破题 concreteBuilder.buildChengTi(); //承题 concreteBuilder.buildQiJiang(); //起讲 concreteBuilder.buildRuTi(); //入题 concreteBuilder.buildQiGu(); //起股 concreteBuilder.buildZhongGu(); //中股 concreteBuilder.buildHouGU(); //后股 concreteBuilder.buildShuGu(); //束股 } } public class Client { public static void main(String[] args) { //创建一个bulider,该builder对八股文的各个部分都进行了实现 System.out.println("第一个builder"); Builder concreteBuilder = new ConcreteBuilder(); //向导演类中注入builder Director director = new Director(concreteBuilder); //组合产品--即组合这篇八股文 director.construct(); //获取写好的八股文 Product product1 = concreteBuilder.getProduct(); System.out.println(product1.toString()); //现在换一个builder,还是按照导演类director规定的流程写八股文 System.out.println("第二个builder"); Builder concreteBuilder2 = new ConcreteBuilder2(); director = new Director(concreteBuilder2); director.construct(); Product product2 = concreteBuilder2.getProduct(); System.out.println(product2.toString()); } }运行结果:
第一个builder
写破题部分
写承题部分
写起讲部分
写入题部分
写起股部分
写中股部分
写后股部分
写束股部分
破题 承题 起讲 入题 起股 中股 后股 束股
第二个builder
写破题部分
写承题部分
写起讲部分
写入题部分
写起股部分
写中股部分
写后股部分
写束股部分
破题2 承题2 起讲2 入题2起股2中股2 后股2 束股2
Product类是产品类,定义了产品的结构---这里定义了八股文的组成部分(类的属性)即get和set方法。
Builder是一个抽象类,声明了创建一个产品要进行的操作---声明了创建八股文八个部分的方法。
Director类是导演类---规定了八股文各个部分的顺序即写八股文的流程
ConcreteBuilder和ConcreteBuilder2分别表示两个建造者---相当于考生,他们分别写了八股文的八个部分
通过这个例子,大家看出建造者模式的有点来了吗?
1.对客户端而言,如果要创建一个复杂的对象,没必要关心其内部的构建流程,只需要关心建造者即可,如果需要对系统进行扩展,不需要修改原有代码,只要新增一个建造者即可。
2.建造者不用关心产品的组建流程,不需要了解各个部分之间的顺序,只要分别创建各个部分即可。
建造者模式适用于创建复杂的对象,且对象内各组件的创建顺序稳定,但各组件自身变化比较大的情况。退一万步讲,即使在最初的时候认为这个对象的稳定的,但后来却仍然发生了变化,使用建造者模式好事有好处的(其实一般不会这样)。
打比方说:皇帝觉得八股文顺序可以调整一下,把承题和起讲换过来,只要把Director类修改掉即可,而不必修改各个建造者。
版权声明:本文为博主原创文章,未经博主允许不得转载。