23种设计模式-建造者模式
一.建造者模式介绍
创建者模式又叫建造者模式,是将一个复杂的对象的构建与它的表示分离,使
得同样的构建过程可以创建不同的表示。创建者模式隐藏了复杂对象的创建过程,它把复杂对象的创建过程加以抽象,通过子类继承或者重载的方式,动态的创建具有复合属性的对象。
二.建造者模式运用
某一天午休时间,经理突然跑过来笑嘻嘻的说
经理:小石头,有个任务要交给你,比较紧急的那种,你接不接?
我: 你先和我说给我多长时间吧。
经理:时间不是问题,我先和你说做的是啥,我们不是要生成报告吗?报告生成那边呢。。。讲了30分钟。
我: (心想:好像我没事一样,好像我很闲一样,好像我工作不饱和一样,但是呢,啥也不敢问,啥也不敢说。。。)好的,没问题,我明天看下代码评估下时间。
经理:等下我和你说下这边东西还是比较重要的,我和你说下哪里需要注意。。。。又讲了30分钟。
然后我开始了看代码的节奏。。。。过了半小时(程序员日常心里活动:这哪个写的代码,真的是shi,shi到家了。。。心里活动30分钟)
看了下,有N种报告,报告都有计分的逻辑,都有报告内部显示内容段顺序的逻辑,都有报告模板。。。有点多等等等。
这个要想下。。。
第二天,老大老大,方案想好了,把这部分东西我用建造者模式+策略模式+模板模式等结合起来,生成前只要调用建造者就行。。。嘟嘟嘟
老大:你去干活吧和我说那么多我也不知道你做成什么样子,我只是个管理。。。快去干活,我还有事呢。
我八字大码走了回来,一个飘逸加甩头坐在了椅子上。。。运起了我的抓键龙抓手。。(此章只讲解建造者其它后面讲)
下面是代码:
模板抽象类
1 public abstract class Template { 2 3 private List<String> sequence = new ArrayList<String>(); 4 5 /** 6 * 头部 7 */ 8 public abstract void head(); 9 10 /** 11 * 说明部分 12 */ 13 public abstract void explain(); 14 15 /** 16 * 报表部分 17 */ 18 public abstract void report(); 19 20 /** 21 * 尾部 22 */ 23 public abstract void rump(); 24 25 final public void build() { 26 for(int i=0;i<this.sequence.size();i++) 27 { 28 String actionName = this.sequence.get(i); 29 if (actionName.equalsIgnoreCase("head")) { 30 this.head(); 31 } else if (actionName.equalsIgnoreCase("explain")) { 32 this.explain(); 33 } else if (actionName.equalsIgnoreCase("report")) { 34 this.report(); 35 } else if (actionName.equalsIgnoreCase("rump")) { 36 this.rump(); 37 } 38 } 39 } 40 41 public void setSequence(List<String> sequence) { 42 this.sequence = sequence; 43 } 44 }
建造者基类
1 public abstract class Builder { 2 public abstract void setSequence(List<String> sequence); 3 4 public abstract Template getTemplate(); 5 }
A模板类
1 public class ATemplate extends Template { 2 3 public void head() 4 { 5 System.out.println("我是A模板头部"); 6 } 7 8 public void explain() 9 { 10 System.out.println("我是A模板说明部分"); 11 } 12 13 public void report() 14 { 15 System.out.println("我是A模板报告"); 16 } 17 18 public void rump() 19 { 20 System.out.println("我是A模板尾部"); 21 } 22 }
A建造者类
1 public class ATemplateBuilder extends Builder { 2 3 ATemplate mdoModel = new ATemplate(); 4 5 @Override 6 public void setSequence(List<String> sequence) 7 { 8 mdoModel.setSequence(sequence); 9 } 10 11 @Override 12 public Template getTemplate() 13 { 14 return mdoModel; 15 } 16 17 }
B模板类
1 public class BTemplate extends Template { 2 3 public void head() 4 { 5 System.out.println("我是B模板头部"); 6 } 7 8 public void explain() 9 { 10 System.out.println("我是B模板说明部分"); 11 } 12 13 public void report() 14 { 15 System.out.println("我是B模板报告"); 16 } 17 18 public void rump() 19 { 20 System.out.println("我是B模板尾部"); 21 } 22 23 }
B建造者类
1 public class BTemplateBuilder extends Builder { 2 BTemplate bTemplate = new BTemplate(); 3 4 @Override 5 public void setSequence(List<String> sequence) 6 { 7 bTemplate.setSequence(sequence); 8 } 9 10 @Override 11 public Template getTemplate() 12 { 13 return bTemplate; 14 } 15 }
调用测试代码
1 List<String> sequence = new ArrayList<String>(); 2 sequence.add("head"); 3 sequence.add("explain"); 4 sequence.add("report"); 5 sequence.add("rump"); 6 7 BTemplateBuilder bBuilder = new BTemplateBuilder(); 8 bBuilder.setSequence(sequence); 9 bBuilder.getTemplate().build(); 10 11 ATemplateBuilder aBuilder = new ATemplateBuilder(); 12 aBuilder.setSequence(sequence); 13 aBuilder.getTemplate().build();
运行结果如下:
我是B模板头部
我是B模板说明部分
我是B模板报告
我是B模板尾部
我是A模板头部
我是A模板说明部分
我是A模板报告
我是A模板尾部
如果想改变顺序和显示只要改变sequence的顺序,现在有个问题客户有很多,但是有些客户会定制模板,不要说明,只要报告等。
下面我们加上导演类
1 public class Director { 2 3 private ArrayList<String> sequence = new ArrayList(); 4 ATemplateBuilder aBuilder = new ATemplateBuilder(); 5 BTemplateBuilder bBuilder = new BTemplateBuilder(); 6 7 public void getAATemplate() 8 { 9 this.sequence.clear(); 10 sequence.add("head"); 11 sequence.add("rump"); 12 aBuilder.setSequence(this.sequence); 13 aBuilder.getTemplate().build(); 14 } 15 public void getABTemplate() 16 { 17 this.sequence.clear(); 18 sequence.add("head"); 19 sequence.add("explain"); 20 sequence.add("report"); 21 aBuilder.setSequence(this.sequence); 22 aBuilder.getTemplate().build(); 23 } 24 public void getBATemplate() 25 { 26 this.sequence.clear(); 27 sequence.add("head"); 28 sequence.add("report"); 29 bBuilder.setSequence(this.sequence); 30 bBuilder.getTemplate().build(); 31 } 32 }
调用测试代码
1 Director director = new Director(); 2 director.getAATemplate(); 3 director.getABTemplate(); 4 director.getBATemplate();
运行结果如下:
我是A模板头部
我是A模板尾部
我是A模板头部
我是A模板说明部分
我是A模板报告
我是B模板头部
我是B模板报告
这样就可以适应不同报告部分的组合了。
三.总结
建造者模式也是创建型模式其中一种,他将复杂对象的构建放到构建对象中,让调用者看不到构建的过程。
优点
建造者模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险。
使用建造者模式可以使客户端不必知道产品内部组成的细节
缺点
建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制
如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。
建造者与工厂模式的区别
从代码中我们可以看到,建造者模式比工厂模式多了个导演者,如果把导演者去掉,其实差不多。但是相对来说,工厂模式适合内部结构比较简单的构建,建造者模式
时候内部结构比较复杂的。工厂模式,将内部放在了工厂中,由工厂和调用方碰头。而建造者因其结构比较复杂,所以衍生出了导演类,建造类将结构建造好,导演类
将建造类中的各个部分安装特定规则或顺序组合,再由导演类和调用方打交道。

浙公网安备 33010602011771号