建造模式
建造模式属于对象创建型模式,建造模式的目的为将复杂对象的构建过程与其部件实现方式分离,使得同样的构建过程可以有不同的表示,同时相同的构建过程也能够适用于不同的部件实现方式。
建造模式的适用性
建造模式主要适用于以下情况:
- 当需要复杂对象的创建方法应该独立于该对象的组成部分的构造方法时。
- 当构造算法必须能够接受被构造的对象使用相同的构造算法有不同的对象表示时。
建造模式的具体实现结构
在上述结构图中,我们可以看到建造模式总共有4个角色:
1、Builder(抽象建造者)角色:抽象建造者为创建Product对象的各个组成部分提供接口。
2、ConcreteBuilder(具体建造者)角色:具体建造者角色通过实现抽象建造者的每个BuildPart方法,并且在对象建造完成后返回结果实例。每一个具体建造者都负责一类产品对象的各个组成部分的建造方法,每一个具体建造者的方法只需要写一次,多个不同的Director(导向器)角色都可以调用生成同一类型下不同的产品。
3、Director(导向器)角色:通过复杂的算法调用具体建造者的方法建造出相应的产品对象。需要说的是同一个导向器实例可以调用不同具体建造者实例的方法构建出不同的产品对象,其中不同具体建造者的方法不能组合使用来构建对象。
4、Procdute(产品)角色:建造模式产生的复杂对象就是产品角色。一个建造模式中可能会有很多个不同类型的产品,每个产品实现的接口都不相同,所以产品角色没有必要抽象出通用的接口。
建造模式的应用
我们平时画一个人要画他的头、手、身体、脚,这些是一个人的组成部分,固定需要画的。我们可以抽象出一个画头、手、身体、脚的接口出来,具体怎么画人可以再通过抽象出来的接口来定。比如说:普通一点的就是一个头、一个身体、两只手、两只脚,但是也可以画出一个人有三头六臂得人等等。下面我们定义一个抽象方法给出实现一个人身上的各个部件:
public abstract class PersonBuilder { public abstract void buileHead(); public abstract void buildLeftHand(); public abstract void buildRightHand(); public abstract void buledBody(); public abstract void buileLeftLeg(); public abstract void buileRightLeg(); public abstract Person getResult(); }
下面定义一个构造人类的类继承抽象类PersonBuilder,分别实现头、身体、手、大腿这些部件的构建。
public class HumanBuilder extends PersonBuilder { Person person =new Person(); @Override public void buileHead() { System.out.println("画一个人类的头"); person.setHead("人类的头"); } @Override public void buildLeftHand() { System.out.println("画一个人类的左手"); person.setLeftHand("人类的左手"); } @Override public void buildRightHand() { System.out.println("画一个人类的右手"); person.setRightHand("人类的右手"); } @Override public void buledBody() { System.out.println("画一个人类的身体"); person.setBody("人类的身体"); } @Override public void buileLeftLeg() { System.out.println("画一个人类的左腿"); person.setLeftLeg("人类的左腿"); } @Override public void buileRightLeg() { System.out.println("画一个人类的右腿"); person.setRightLeg("人类的右腿"); } @Override public Person getResult(){ return person; } }
产品类Person
public class Person { private String Head; private String LeftHand; private String RightHand; private String Body; private String LeftLeg; private String RightLeg; public String getHead() { return Head; } public void setHead(String head) { Head = head; } public String getLeftHand() { return LeftHand; } public void setLeftHand(String leftHand) { LeftHand = leftHand; } public String getRightHand() { return RightHand; } public void setRightHand(String rightHand) { RightHand = rightHand; } public String getBody() { return Body; } public void setBody(String body) { Body = body; } public String getLeftLeg() { return LeftLeg; } public void setLeftLeg(String leftLeg) { LeftLeg = leftLeg; } public String getRightLeg() { return RightLeg; } public void setRightLeg(String rightLeg) { RightLeg = rightLeg; } }
最后通过一个PersonDirector引导器来完成一个人的组装构建,通过调用HumanBuilder的方法通过不同的算法可以组建一个有一个头、两个手、一个身体、两只脚的正常人,也可以构建出一个拥有三头六臂的神人,还可以构建出一位只有一只手的残疾人,这就是我们所说的通过不同的构建方法调用同一个建造器可以得到不同的表示。同样的道理还可以再定义一个外星人的AlienBuilder建造器,通过组装个头、两个手、一个身体、两只脚的人类的组装方法得到与人类完全不同的外星人对象。
所以说不同的构造方法可以得到复杂对象的不同表示,相同的构造方法也可以创造出不同的对象的表示。
下面给出一种组装一个头、两个手、一个身体、两只脚的正常人的构造方法。
public class PersonDirector { private PersonBuilder personBuilder; public PersonDirector(PersonBuilder personBuilder) { this.personBuilder = personBuilder; } public void CreatePerson() { personBuilder.buileHead(); personBuilder.buildLeftHand(); personBuilder.buildRightHand(); personBuilder.buledBody(); personBuilder.buileLeftLeg(); personBuilder.buileRightLeg(); } }
Clien调用
public class Client { public static void main(String[] args) { PersonBuilder personBuilder = new HumanBuilder(); PersonDirector personDirector = new PersonDirector(personBuilder); personDirector.CreatePerson(); Person person = personBuilder.getResult() } }
画一个人类的头
画一个人类的左手
画一个人类的右手
画一个人类的身体
画一个人类的左腿
画一个人类的右腿
总结
建造模式可以很轻易的就改变一个产品的内部表示,通过定义一个新的生成器在客户端就可以调用不同的生成器产生不同的对象表示;同时建造模式也将产品的构建过程和表示分离开,使得客户不用知道一个产品的内部构造是什么样的,只需要调用生成器的接口就可以建造出一个需要的对象;最后建造模式可以使得使用者能够对产品的构建过程进行更加精确的控制,通过导向器一一步一步的建造出一个复杂的对象。
建造模式和抽象工厂模式的区别在于建造模式更加注重的是一步一步构建产品的过程,而抽象工厂模式更加注重一系列相关联的产品部件组建出一个产品。建造模式是一步一步的构建产品,而抽象工厂模式是立即就生成对象。