创建型模式之建造者模式(Builder)

建造者模式的精髓在于:对构建过程进行解耦
一个对象的创建是非常复杂的,需要一步一步地操作,每个步骤都可能是有关联或依赖的,
最重要的是同一套建造流程是需要被不同的建造者复用的,因此需要分层抽象以松耦
目标:在不改变创建过程的前提下,可以创建出不同表象的对象

建造者模式的意图在于将一个对象复杂的建造过程(步骤多)从业务中分离出去,同时对建造过程进行抽象,从而使得在“建造”这一层面具有了可扩展性,这有就可以方便地通过切换建造过程而完成新型对象的创建,建造者模式将抽象出来的建造过程交由“指挥者”来管理,“指挥者”控制建造流程,并且通过指挥者获取建造的对象,用户不必再关系对象的创建过程。分离出来的建造过程,也可以被很好地管理,避免与具体的使用业务混杂在一起。


场景:软件系统通常都会有许多设置项,我们会通过一个Config对象来获取这些配置项目,比如端IP地址、口号、是否备份等,通常我们通过解析一个xml配置文件获取到这些属性值然后赋值给我们的Config对象。

用建造者模式来表述:

由于xml属性很多,建造过程复杂,不同的xml文件副本,属性值都不相同,这个时候,每一个xml文件副本都可以看作是一个具体的建造者,建造者只是可以获取到属性值,但却不知道如何完成Config对象的创建规则,指挥者就负责完成对象的创建过程,如此,对象的创建过程与表象分离开来!


示例代码:

class Config {
    private String ip;
    private int port;
    private boolean bakEnabled;
    public String getIp() {
        return ip;
    }
    public void setIp(String ip) {
        this.ip = ip;
    }
    public int getPort() {
        return port;
    }
    public void setPort(int port) {
        this.port = port;
    }
    public boolean isBakEnabled() {
        return bakEnabled;
    }
    public void setBakEnabled(boolean bakEnabled) {
        this.bakEnabled = bakEnabled;
    }
    @Override
    public String toString() {
        return "Config{" +
                "ip='" + ip + '\'' +
                ", port=" + port +
                ", bakEnabled=" + bakEnabled +
                '}';
    }
}
abstract class ConfigBuilder {
    protected Config config;
    public ConfigBuilder() {
        this.config = new Config();
    }
    public Config getConfig() {
        return config;
    }
    public abstract void buildIp();
    public abstract void buildPort();
    public abstract void buildBakEnabled();
}
// 构建 指挥者
class ConfigBuildDirector {
    private ConfigBuilder builder;
    public void setBuilder(ConfigBuilder builder) {
        this.builder = builder;
    }
    public void constructConfig() {
        // 这里可以控制构建细节,比如许多判断逻辑和其它业务逻辑等
        builder.buildIp();//第一步:构建IP地址
        // others
        builder.buildPort();//第二步:构建端口
        // others
        builder.buildBakEnabled();//第二步:构建是否需要备份
        // others
    }
}
class BakBuilder extends ConfigBuilder {
    @Override
    public void buildIp() {
        config.setIp("127.0.0.1");
    }
    @Override
    public void buildPort() {
        config.setPort(80);
    }
    @Override
    public void buildBakEnabled() {
        config.setBakEnabled(true);//设置 “备份” 属性位true
    }
}
class NoneBakBuilder extends ConfigBuilder {
    @Override
    public void buildIp() {
        config.setIp("127.0.0.1");
    }
    @Override
    public void buildPort() {
        config.setPort(80);
    }
    @Override
    public void buildBakEnabled() {
        config.setBakEnabled(false);//设置 “备份” 属性位false
    }
}

/**
 *  建造者模式的精髓在于:对构建过程进行解耦
 *  一个对象的创建是非常复杂的,需要一步一步地操作,每个步骤都可能是有关联或依赖的,
 *  最重要的是同一套建造流程是需要被不同的建造者复用的,因此需要分层抽象以松耦
 *  目标:在不改变创建过程的前提下,可以创建出不同表象的对象
 */
public class Test {
    public static void main(String[] args) {
        Config config;// 目标对象

        // 建造指挥者,规划建造者的工作流程,一个系统中,通常只有一个建造指挥者
        ConfigBuildDirector buildDirector = new ConfigBuildDirector();

        // 建造者用以完成特定步骤的创建过程,不同的建造者的建造细节不相同
        ConfigBuilder bakBuilder = new BakBuilder();//一个建造者
        ConfigBuilder noneBakBuilder = new NoneBakBuilder();//另一个建造者

        // 指挥第一个创建
        buildDirector.setBuilder(bakBuilder);
        buildDirector.constructConfig();

        // 指挥第二个创建
        buildDirector.setBuilder(noneBakBuilder);
        buildDirector.constructConfig();


        // 以下应该是用户获取目标对象的业务代码,用户将“Builder”交给“Director”指挥构建以后,
        // 用户再通过“Builder”获取建造的目标对象

        // 指挥完成建造后,通过建造者取出目标对象实例
        config = bakBuilder.getConfig();
        System.out.println(config);

        // 指挥完成建造后,通过建造者取出目标对象实例
        config = noneBakBuilder.getConfig();
        System.out.println(config);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值