建造者模式的Java实现

建造者模式

  • 建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

  • 一个Builder类会一步一步构造最终的对象,该Builder类是独立于其他对象的。

介绍

场景:建造一个复杂的产品或者开发过程中构建对象过于复杂,则需要进行分步处理。

意图:将一个复杂的构建与其装配相分离,使得同样的构建过程可以创建不同的表示。

本质:

  • 分离了对子组件的单独构造(由Builder来负责)和装配(由Director负责),从而可以构件出复杂的对象。这个模式适用于:某个对象构造复杂的情况下使用。
  • 由于实现了构件和装配的解耦,不同的构建器,相同的装配过程也可以做出不同的对象;相同的构建器,不同的装配过程也可以做出不同的对象。
  • 因此,实现了构建算法、装配算法的解耦,实现了更好的复用。

何时使用:一些基本部件不会变,而其组合经常变化的时候。

如何解决:将变与不变分离开。

关键代码:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。

使用场景:

  • 需要生成的对象具有复杂的内部结构
  • 需要生成的对象内部属性本身相互依赖。

应用实例: 

  • 去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"
  • JAVA 中的 StringBuilder的append方法
  • SQL中的PrepareStatement
  • JDOM中DomBuilder,SAXBuilder

优点:

  • 建造者独立,易扩展
  • 便于控制细节风险

缺点: 

  • 产品必须有共同点,范围有限制
  • 如内部变化复杂,会有很多的建造类

注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。

实现

步骤1:创建宇宙飞船框架和宇宙飞船组件

package com.ly.builder;

/**
 * liyang 2020-07-12
 * 创建宇宙飞船框架和宇宙飞船组件
 */

public class SpaceCraft {
    private OrbitalModule orbitalModule; //轨道舱模块
    private Engine engine;               //发动机
    private EscapeTower escapeTower;     //逃逸仓

    public OrbitalModule getOrbitalModule() {
        return orbitalModule;
    }

    public void setOrbitalModule(OrbitalModule orbitalModule) {
        this.orbitalModule = orbitalModule;
    }

    public Engine getEngine() {
        return engine;
    }

    public void setEngine(Engine engine) {
        this.engine = engine;
    }

    public EscapeTower getEscapeTower() {
        return escapeTower;
    }

    public void setEscapeTower(EscapeTower escapeTower) {
        this.escapeTower = escapeTower;
    }

    public void launch() {
        System.out.println("发射宇宙飞船");
    }
}


class OrbitalModule {
    private String name;

    public OrbitalModule(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

class Engine {
    private String name;

    public Engine(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

class EscapeTower {
    private String name;

    public EscapeTower(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

步骤2:创建建造者和装配者接口

package com.ly.builder;

public interface SpaceCraftBuilder {
    OrbitalModule buildOrbitalModule();
    Engine buildEngine();
    EscapeTower buildEscapeTower();
}
package com.ly.builder;

public interface SpaceCraftDirector {
    SpaceCraft directSpaceCraft();
}

步骤3:创建真实的建造者和装配者(装配建造者构建的零部件,返回装配好的SpaceCraft)

package com.ly.builder;

public class LySpaceCraftBuilder implements SpaceCraftBuilder{
    @Override
    public OrbitalModule buildOrbitalModule() {
        System.out.println("ly-构建轨道舱");
        return new OrbitalModule("ly-轨道舱");
    }

    @Override
    public Engine buildEngine() {
        System.out.println("ly-构建发动机");
        return new Engine("ly-发动机");
    }

    @Override
    public EscapeTower buildEscapeTower() {
        System.out.println("ly-构建逃逸塔");
        return new EscapeTower("ly-逃逸塔");
    }
}
package com.ly.builder;

public class LySpaceCraftDirector implements SpaceCraftDirector {
    //装配置自然需要调用构造者生产的组件
    private SpaceCraftBuilder spaceCraftBuilder;

    public LySpaceCraftDirector(SpaceCraftBuilder spaceCraftBuilder) {
        super();
        this.spaceCraftBuilder = spaceCraftBuilder;
    }

    @Override
    public SpaceCraft directSpaceCraft() {
        //使用建造者生产组件
        OrbitalModule orbitalModule = spaceCraftBuilder.buildOrbitalModule();
        Engine engine = spaceCraftBuilder.buildEngine();
        EscapeTower escapeTower = spaceCraftBuilder.buildEscapeTower();
        //使用生产的组件进行set组装
        SpaceCraft spaceCraft = new SpaceCraft();
        spaceCraft.setOrbitalModule(orbitalModule);
        spaceCraft.setEngine(engine);
        spaceCraft.setEscapeTower(escapeTower);
        //组装完return出去
        return spaceCraft;
    }
}

步骤4:客户端测试

package com.ly.builder;

public class Client {
    public static void main(String[] args) {
        SpaceCraftDirector spaceCraftDirector = new LySpaceCraftDirector(new LySpaceCraftBuilder());

        SpaceCraft spaceCraft = spaceCraftDirector.directSpaceCraft();

        System.out.println(spaceCraft.getOrbitalModule().getName());
        System.out.println(spaceCraft.getEngine().getName());
        System.out.println(spaceCraft.getEscapeTower().getName());

        spaceCraft.launch();
    }
}

结果:

ly-构建轨道舱
ly-构建发动机
ly-构建逃逸塔
ly-轨道舱
ly-发动机
ly-逃逸塔
发射宇宙飞船

Process finished with exit code 0

参考资料:

https://www.runoob.com/design-pattern/builder-pattern.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值