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 }
View Code
建造者基类
1 public abstract class Builder {
2     public abstract void setSequence(List<String> sequence);
3 
4     public abstract Template getTemplate();
5 }
View Code

  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 }
View Code

 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 }
View Code

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 }
View Code

 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 }
View Code

调用测试代码

 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();
View Code

运行结果如下:

我是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 }
View Code

调用测试代码

1      Director director = new Director();
2         director.getAATemplate();
3         director.getABTemplate();
4         director.getBATemplate();
View Code

运行结果如下:

我是A模板头部
我是A模板尾部
我是A模板头部
我是A模板说明部分
我是A模板报告
我是B模板头部
我是B模板报告

这样就可以适应不同报告部分的组合了。

 

三.总结

建造者模式也是创建型模式其中一种,他将复杂对象的构建放到构建对象中,让调用者看不到构建的过程。

优点

建造者模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险。

使用建造者模式可以使客户端不必知道产品内部组成的细节

缺点

建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制

如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

建造者与工厂模式的区别

从代码中我们可以看到,建造者模式比工厂模式多了个导演者,如果把导演者去掉,其实差不多。但是相对来说,工厂模式适合内部结构比较简单的构建,建造者模式

时候内部结构比较复杂的。工厂模式,将内部放在了工厂中,由工厂和调用方碰头。而建造者因其结构比较复杂,所以衍生出了导演类,建造类将结构建造好,导演类

将建造类中的各个部分安装特定规则或顺序组合,再由导演类和调用方打交道。

 

 

 
 
posted @ 2019-08-06 18:15  海上翱翔  阅读(130)  评论(0)    收藏  举报