1. 定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示,建造者模式是一种对象创建型模式
2. 建造者模式结构图:
3. 结构图中的角色分析
- Builder(抽象建造者):创建各个部件的抽象接口,可以是抽象类或接口
- ConcreteBuilder(具体建造者):实现Builder接口,实现各个部件的具体构造和装配方法
- Product(产品角色):被构建的复杂对象,包含多个组成的部件具体建造者创建该产品内部表示并定义其装配过程
- Director(指挥者):安排复杂对象的建造次序,指挥者与抽象建造者是关联关系,可在其construct()建造方法中调用建造者对象的部件与装配方法,完成复杂对象的建造,客户端一般只需与指挥者进行交互
4. 核心代码
1) 复杂对象
class Product{
private String partA;//定义部件,部件可以是任意类型,包括值类型和引用类型
private String partB;
private String partC;
}
2) 抽象建造者
abstract class Builder{
//创建产品对象
protectd Product product = new Product();
public abstract void buildPartA();
public abstract void buildPartB();
public abstract void buildPartC();
//返回产品对象
public Product getResult(){
return product;
}
}
3) 指挥者Director
class Director{
private Builder builder;
public Director(Builder builder){
this.builder = builder;
}
//产品构建与组装方法
public Product construct(){
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
return builder.getResult();
}
}
5. 建造者模式与抽象工厂模式的异同
- 建造者模式返回一个完整的复杂产品,而抽象工厂模式返回一系列相关产品;
- 抽象工厂模式中,客户端通过具体工厂生产所需对象;建造者模式中客户端通过指定建造者类型并指导Director类生产对象,侧重构造复杂对象的过程
- 若抽象工厂模式看成汽车配件生产厂,生成不同类型的汽车配件,则建造者模式就是一个汽车组装厂,组装配件成一辆完整的汽车;
6. 建造者模式实践案例
1) 游戏角色的结构图
2) 代码实现
//Actor角色类:复杂产品
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;
}
}
/**
* 角色建造者
*
* @author Zach
*/
public abstract class ActorBuilder {
protected Actor actor = new Actor();
public abstract void buildType();
public abstract void buildSex();
public abstract void buildFace();
public abstract void buildCostume();
public abstract void buildHaitstyle();
//工厂方法,返回一个完整的游戏角色对象
public Actor createActor() {
return actor;
}
//改进版,省略了Director类ActorController
/*public Actor construct() {
this.buildType();
this.buildCostume();
this.buildSex();
this.buildFace();
this.buildHaitstyle();
return actor;
}*/
}
//恶魔角色建造器:具体建造者
public class DevilBuilder extends ActorBuilder {
@Override
public void buildType() {
actor.setType("恶魔");
}
@Override
public void buildSex() {
actor.setSex("妖");
}
@Override
public void buildFace() {
actor.setFace("丑陋");
}
@Override
public void buildCostume() {
actor.setCostume("黑衣");
}
@Override
public void buildHaitstyle() {
actor.setHairstyle("光头");
}
}
package com.zach.builder;
//具体建造器:天使角色建造器
public class AngelBuilder extends ActorBuilder {
@Override
public void buildType() {
actor.setType("天使");
;
}
@Override
public void buildSex() {
actor.setSex("女");
}
@Override
public void buildFace() {
actor.setFace("漂亮");
}
@Override
public void buildCostume() {
actor.setCostume("白裙");
}
@Override
public void buildHaitstyle() {
actor.setHairstyle("披肩长发");
}
}
//英雄角色建造器:具体建造者
public class HeroBuilder extends ActorBuilder {
@Override
public void buildType() {
actor.setType("英雄");
}
@Override
public void buildSex() {
actor.setSex("男");
}
@Override
public void buildFace() {
actor.setFace("英俊");
}
@Override
public void buildCostume() {
actor.setCostume("盔甲");
}
@Override
public void buildHaitstyle() {
actor.setHairstyle("飘逸");
}
}
//游戏角色创建控制器:指挥者
public class ActorController {
//逐步构建复杂产品对象
public Actor construct(ActorBuilder ab) {
Actor actor;
ab.buildType();
ab.buildSex();
ab.buildFace();
ab.buildCostume();
ab.buildHaitstyle();
actor = ab.createActor();
return actor;
}
}
//客户端代码
public class Client {
public static void main(String[] args) {
ActorBuilder ab = new AngelBuilder();
ActorController ac = new ActorController();
Actor actor = ac.construct(ab);
String type = actor.getType();
System.out.println(type + "的外观:");
System.out.println("性别:" + actor.getSex());
System.out.println("面容:" + actor.getFace());
System.out.println("服装:" + actor.getCostume());
System.out.println("发型:" + actor.getHairstyle());
}
}
7. 建造者模式总结
1) 主要缺点
- 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,若产品差异性很大,就不适合使用建造者模式
- 如果产品产品内部结构复杂多变,会使得系统很庞大
2) 使用场景
- 生成的产品对象有复杂的内部结构,包含多个成员变量
- 生成的产品对象的属性相互依赖,需要指定其生成顺序
- 对象的创建过程独立于创建该对象的类
- 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品