建造者模式

建造者模式

概念

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

角色

  • 抽象建造者: 为创建一个产品对象的各个部分指定抽象接口。通常有两类方法,一类是buildPartX(),用于创建复杂对象的各个部分;另一类是getResult(),用于返回复杂对象
  • 具体建造者: 实现了抽象建造者的接口,实现了各个部分的具体构造和装配方法,定义并明确所创建的复杂对象
  • 产品: 被构造的复杂对象,包括多个组件
  • 指挥者: 安排复杂对象的建造次序,客户端一般只需要和指挥者进行交互

UML图如下

在这里插入图片描述

建造者模式的优缺点

优点
  • 客户端不需要知道产品内部组成,将产品本身与产品的创建过程进行解耦
  • 每一个具体建造者都相对独立。方便替换具体建造者或增加新的具体建造者,符合开闭原则
  • 将复杂产品的创建步骤分解在不同点的方法中,使得创建过程更加清晰
缺点
  • 如果产品间差异很大,不适合用建造者模式
  • 如果产品的内容变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大

适合环境

  • 产品对象有复杂的内部结构
  • 产品对象的属性相互依赖,需要指定其生产顺序
  • 创建过程独立于创建该对象的类
  • 隔离复杂对象的创建和使用

例子

我们现在要开发一款角色扮演游戏,玩具可以创建不同的角色,不同的角色具有不同的能力。角色作为游戏的一个重要组成部分,需要对角色进行设计,而且伴随着游戏的更新会不断添加新角色,游戏角色是一个复杂对象,包含性别、发型、服装等都有所差异。如天使拥有美丽的面容和披肩长发,身穿白裙;恶魔及其丑陋并且光头穿一身黑衣服。我们需要创建出该游戏的角色

分析

我们先将实体与简单工厂的角色一一对应

  • 复杂产品对象: Action
  • 抽象建造者: ActionBuilder
  • 具体建造者: HeroBuilder
  • 具体建造者: AngelBuilder
  • 具体建造者: DevilBuilder
  • 指挥者: ActionController

看不懂不要紧,我们先看UML图,在看代码应该就能理解了

[外链图片转存失败(img-5OPwRgiC-1564501958249)(https://raw.githubusercontent.com/kevinlu98/cloudimg/master/data/QQ20190730-232645@2x.png)]

编码

当然,具体的游戏开发比我们这个伪代码难多了,我们就是模拟一下这个过程

Action.java

package cn.kevinlu98.builder;

/**
 * @Author: Kevin·Lu
 * @Date: 12:20 AM 2019/7/28
 * @Description: 游戏角色类,充当复杂产品对象。
 */
public class Actor {

    private String type;        //角色类型
    private String sex;         //性别
    private String face;        //脸型
    private String costume;     //服装
    private String hairstyle;   //发型

    //getter and setter
}

ActionBuilder.java

package cn.kevinlu98.builder;

/**
 * @Author: Kevin·Lu
 * @Date: 12:24 AM 2019/7/28
 * @Description: 游戏角色建造者,充当抽象建造者
 */
public abstract class ActorBuilder {
    protected Actor actor = new Actor();

    public abstract void buildType();

    public abstract void buildSex();

    public abstract void buildFace();

    public abstract void buildCustomer();

    public abstract void buildHairstyle();

    /**
     * 工厂方法,返回一个完整的角色对象
     *
     * @return
     */
    public Actor createActor() {
        return actor;
    }
}

HeroBuilder.java

package cn.kevinlu98.builder;

/**
 * @Author: Kevin·Lu
 * @Date: 12:27 AM 2019/7/28
 * @Description: 英雄角色建造者,充当具体建造者
 */
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 buildCustomer() {
        actor.setCostume("盔甲");
    }

    @Override
    public void buildHairstyle() {
        actor.setHairstyle("飘逸");
    }
}

AngelBuilder.java

package cn.kevinlu98.builder;

/**
 * @Author: Kevin·Lu
 * @Date: 12:29 AM 2019/7/28
 * @Description: 天使角色建造者,充当具体建造者
 */
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 buildCustomer() {
        actor.setCostume("白裙");
    }

    @Override
    public void buildHairstyle() {
        actor.setHairstyle("披肩长发");
    }
}

DevilBuilder.java

package cn.kevinlu98.builder;

/**
 * @Author: Kevin·Lu
 * @Date: 12:30 AM 2019/7/28
 * @Description: 恶魔角色建造者,充当具体建造者
 */
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 buildCustomer() {
        actor.setCostume("黑衣");
    }

    @Override
    public void buildHairstyle() {
        actor.setHairstyle("光头");
    }
}

ActionController.java

package cn.kevinlu98.builder;

/**
 * @Author: Kevin·Lu
 * @Date: 12:31 AM 2019/7/28
 * @Description: 角色控制器,充当指挥者
 */
public class ActorController {
    public Actor construct(ActorBuilder builder) {
        builder.buildCustomer();
        builder.buildFace();
        builder.buildHairstyle();
        builder.buildSex();
        builder.buildType();
        return builder.createActor();
    }
}

config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<config>
    <className>cn.kevinlu98.builder.AngelBuilder</className>
</config>

XMLUtil.java(略,和之前的大同小异)

运行结果

在这里插入图片描述

至此,工厂方法设计模式介绍完成,希望能帮助到您

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值