转载

建造者模式

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

正文到此结束
Loading...