建造者模式是一种对象创建型模式,它将客户端与包含多个部件的复杂对象的创建过程分离,客户端无须知道复杂对象的内部组成部分与装配方式,秩序要知道所需建造者的类型即可。
建造者模式的结构
1.Builder(抽象建造者):他为创建一个产品对象的各个部件指定抽象接口,在这种接口中一般会有两种方法.1:buildPartX():用来构建对象的各个部件,2:getResult():可以用来返回复杂对象
2.ConcreteBuilder(具体建造者):它实现了build接口,实现了各个部件的具体构造和装配方法,定义并明确所需要创建的复杂对象。
3.Product(产品类):它就是需要被创建的复杂对象,它的构成包含了多个组成部件,具体的建造者创建产品内部表示并定义它的装配过程
4.Director(指挥者):指挥者又称为导演类,它的作用是负责安排这个对象的具体的构造顺序
案例:
游戏原件公司需要开发一款居于角色扮演的多人在线网络游戏,玩家可以在游戏中扮演虚拟世界中的一个特定角色,
角色根据不同的游戏情节和统计数据具有不同的能力,其实也就是(力量,魔法,技能上的不同),角色也会随着不断的升级
而拥有更加强大的能力
作为游戏的一个重要组成部分,需要对游戏角色进行设计,而且随着改游戏的升级将不断增加新的角色,通过分析发现,游戏角色
是一个复杂的对象,它包含性别,脸型等多个组成部分,不同类型的游戏角色,它的性别,脸型,服装都是不一样的
天使:美丽的面容,披肩的长发,然后穿着是一件白色的裙子
恶魔:丑陋的面容,光头,一件刺眼的黑衣
无论是何种造型的游戏角色,它的床架步骤都是大同小异的,都需要逐步创建其组成部分,再将各组成部分装配成一个完整的游戏角色
产品类
package com.designpatten.builder.demo2;
public class Actor {
private String type;
private String sex;
private String face;
private String costume;
private String hairStyle;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getFace() {
return face;
}
public void setFace(String face) {
this.face = face;
}
public String getCostume() {
return costume;
}
public void setCostume(String costume) {
this.costume = costume;
}
public String getHairStyle() {
return hairStyle;
}
public void setHairStyle(String hairStyle) {
this.hairStyle = hairStyle;
}
@Override
public String toString() {
return "Actor{" +
"type='" + type + '\'' +
", sex='" + sex + '\'' +
", face='" + face + '\'' +
", costume='" + costume + '\'' +
", hairStyle='" + hairStyle + '\'' +
'}';
}
}
构建者的抽象类
package com.designpatten.builder.demo2;
public abstract class ActorBuilder {
protected Actor actor = new Actor();
abstract void buildType();
abstract void buildSex();
abstract void buildFace();
abstract void buildCostume();
abstract void buildHairStyle();
public Actor getActor(){
return actor;
}
}
具体的构造者类(天使)
package com.designpatten.builder.demo2;
public class AngleBuilder extends ActorBuilder {
@Override
void buildType() {
actor.setType("天使");
}
@Override
void buildSex() {
actor.setSex("男");
}
@Override
void buildFace() {
actor.setFace("脸长的很好看");
}
@Override
void buildCostume() {
actor.setCostume("穿着白色的长裙");
}
@Override
void buildHairStyle() {
actor.setHairStyle("头发很好看,不是光头");
}
}
具体的构造者类(恶魔)
package com.designpatten.builder.demo2;
public class DevilBuilder extends ActorBuilder {
@Override
void buildType() {
actor.setType("恶魔");
}
@Override
void buildSex() {
actor.setSex("男");
}
@Override
void buildFace() {
actor.setFace("脸长的很丑");
}
@Override
void buildCostume() {
actor.setCostume("穿着黑色的衣服");
}
@Override
void buildHairStyle() {
actor.setHairStyle("光头");
}
}
指挥类
package com.designpatten.builder.demo2;
/**
* 角色的指导类
*/
public class ActorDirector {
private ActorBuilder actorBuilder;
ActorDirector(ActorBuilder actorBuilder){
this.actorBuilder = actorBuilder;
}
public void setActorBuilder(ActorBuilder actorBuilder){
this.actorBuilder = actorBuilder;
}
/**
* 构造一个角色对象
* @return
*/
public Actor construct(){
actorBuilder.buildType();
actorBuilder.buildSex();
actorBuilder.buildCostume();
actorBuilder.buildFace();
actorBuilder.buildHairStyle();
return actorBuilder.getActor();
}
}
客户端
package com.designpatten.builder.demo2;
public class Client {
public static void main(String[] args) {
ActorDirector actorDirector = new ActorDirector(new AngleBuilder());
Actor construct = actorDirector.construct();
System.out.println(construct);
}
}
运行结果
这样如果想要增加新的角色的时候只需要增加对应的建造者的类就可以了,原有的代码无需修改
建造者模式的优点:
1.在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象
2.每一个具体的建造者之间都相对比较独立,与其他的建造者都没什么关系,因此可以很方便的替换具体的建造者或者是增加新的建造者,这个符合开闭原则
建造者模式的缺点:
1.建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大的话,那就不适合使用这个模式
2.如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变的很大,这样会增加系统的理解难度和运行成本。