建造者模式

GOF给建造者模式的定义是:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

来看看建造者模式的组成:

1.产品角色:建造中的复杂对象、它要包含哪些定义组件的类,包括将这些组件装配成产品的接口。

2.抽象建造者角色:这个角色用来规范产品对象的各个组成成分的建造。一般而言,此角色独立于应用程序的业务逻辑。

3.具体建造者角色:担任这个角色的是与应用程序紧密相关的类,它们在指导者的调用下创建产品实例。这个角色在实现抽象角色提供的方法的前提下,达到完成产品组装,提供成品的功能。

4.指导者角色:调用具体建造者角色以创建产品对象。指导者并没有产品类的具体知识,真正拥有产品类的具体知识是具体建造者对象。

来看看这些角色组成的类图:

建造者模式和工厂方法模式都是创建模式。下面通过代码来讲解来熟悉建造者模式:

产品角色:

 1 package com.bluemsun.BuilderModel;
 2 
 3 
 4 /**
 5  * 产品类,一个Person的产品模型
 6  * @author zhouxy
 7  *
 8  */
 9 public class PersonModel {
10     private Body body;
11     private Soul soul;
12     
13     public Body getBody() {
14         return body;
15     }
16     public void setBody(Body body) {
17         this.body = body;
18     }
19     public Soul getSoul() {
20         return soul;
21     }
22     public void setSoul(Soul soul) {
23         this.soul = soul;
24     }
25     @Override
26     public String toString() {
27         return "Person ["+body.toString()+","+soul.toString()+"]";
28     }
29 }

产品角色中body,soul组件的定义如下:

 1 package com.bluemsun.BuilderModel;
 2 
 3 public class Body {
 4     private int eyes;
 5     private int ear;
 6     private int nose;
 7     private int mouse;
 8     private int hand;
 9     private int leg;
10     
11     /*此处省略setter,getter方法*/
12     
13     public Body(int eyes, int ear, int nose, int mouse, int hand, int leg) {
14         super();
15         this.eyes = eyes;
16         this.ear = ear;
17         this.nose = nose;
18         this.mouse = mouse;
19         this.hand = hand;
20         this.leg = leg;
21     }
22     @Override
23     public String toString() {
24         return "Body [eyes=" + eyes + ", ear=" + ear + ", nose=" + nose
25                 + ", mouse=" + mouse + ", hand=" + hand + ", leg=" + leg + "]";
26     }
27 }
 1 package com.bluemsun.BuilderModel;
 2 
 3 public class Soul {
 4     private String soul_type;
 5 
 6     /*此处省略setter,getter方法*/
 7     public Soul(String soul_type) {
 8         super();
 9         this.soul_type = soul_type;
10     }
11     @Override
12     public String toString() {
13         return "Soul [soul_type=" + soul_type + "]";
14     }
15 }

抽象建造者角色:

 1 package com.bluemsun.BuilderModel;
 2 
 3 /**
 4  * 抽象建造者接口,指明建造一个Person产品需要的组件(方法)
 5  * @author zhouxy
 6  *
 7  */
 8 public interface Builder{
 9     
10     public void buildBody();//构建body组件
11     public void buildSoul();//构建soul组件
12     
13     public PersonModel getPersonModel();//通过上面两个组件的完成,在这里将组件组装,返回成品对象
14 }

具体建造者角色:

 1 package com.bluemsun.BuilderModel;
 2 
 3 /**
 4  * 具体建造者类,实现Builder
 5  * @author zhouxy
 6  *
 7  */
 8 public class PersonBuilder implements Builder{
 9     private PersonModel personModel = new PersonModel();//创建一个待组装的对象
10     
11     @Override
12     public void buildBody() {    //生产真正组件
13         Body body = new Body(2, 2, 1, 1, 2, 1);
14         personModel.setBody(body);
15     }
16 
17     @Override
18     public void buildSoul() {    //生产真正组件
19         Soul soul = new Soul("高尚的");
20         personModel.setSoul(soul);
21     }
22 
23     @Override
24     public PersonModel getPersonModel() { //将上面实际产生的组件进行组装
25         return personModel;    //返回成品
26     }
27 }

指导者角色:

 1 package com.bluemsun.BuilderModel;
 2 
 3 
 4 /**
 5  * 指导者.指导者根据不同的builder指导创建不同成品
 6  * @author zhouxy
 7  *
 8  */
 9 public class Director {
10     private Builder builder;
11     
12     public Director(Builder builder){
13         this.builder = builder;
14     }
15     
16     public void construct(){    //根据客户端提供的builder产生与builder对应的组件
17         builder.buildBody();
18         builder.buildSoul();
19     }
20 }

客户端代码:

 1 package com.bluemsun.BuilderModel;
 2 
 3 
 4 /**
 5  * 客户端代码
 6  * @author zhouxy
 7  *
 8  */
 9 public class Client {
10     public static void main(String[] args) {
11         Builder builder = new PersonBuilder();    
12         Director director = new Director(builder);
13         director.construct();
14         PersonModel personModel = builder.getPersonModel();
15         
16         System.out.println(personModel.toString());
17         
18         /*builder = new SuperManBuilder();
19         director = new Director(builder);
20         director.construct();
21         personModel = builder.getPersonModel();
22         
23         System.out.println(personModel.toString());*/
24     }
25 }

在客户端代码中,我们创建了一个具体建造者对象,并把这个对象交给指导者,指导者将会根据它的信息指导创建具体产品实例。如果现在我们需要创建另外一种产品实例,我们仅仅需要定义这种产品具体实现(代码如下),其他部分的代码不需要修改,客户端也仅仅只是需要增加上面注释部分的代码即可。

 1 package com.bluemsun.BuilderModel;
 2 
 3 /**
 4  * 另一种具体产品的实现
 5  * @author zhouxy
 6  *
 7  */
 8 
 9 public class SuperManBuilder implements Builder {
10     
11     private PersonModel personModel = new PersonModel();
12     
13     @Override
14     public void buildBody() {
15         Body body = new Body(4, 4, 2, 2, 4, 4);
16         personModel.setBody(body);
17     }
18 
19     @Override
20     public void buildSoul() {
21         Soul soul = new Soul("善良的,伟大的");
22         personModel.setSoul(soul);
23     }
24 
25     @Override
26     public PersonModel getPersonModel() {
27         
28         return personModel;
29     }
30 
31 }

建造模式的优点:

1.建造者模式可以使得产品内部的表象独立变化。在原来的工厂方法模式中,产品内部的表象是由产品自身来决定的,而在建造者模式中则是“外部化”为由具体的建造者来负责。这样定义一个新的具体建造者角色(就像上面的SuperManBuilder)就可以改变产品的内部表象,符合“开闭原则”。

2.建造者模式使得客户端不需要知道太多产品内部的细节。他将复杂对象的组件和表示方式封装在一个具体的建造角色中,而且由指导者类协调建造者角色来得到具体产品实例。

原文地址:https://www.cnblogs.com/zhouxuanyu/p/4585593.html