设计模式2 - 建造者模式

22 篇文章 0 订阅
6 篇文章 0 订阅

建造者模式,在一些框架中,常和工厂模式一起使用,所以这里对于以后的框架的理解非常重要,所以这里学习一下

建造者模式

1. 场景

​ 我们要建造一个复杂的产品。比如:神舟飞船,IPhone。这个复杂的产品的创建(比如iPhone),有这样问题需要处理:

  • iPhone的拼装,需要很多小的组件。也就是说我们除了要构建这些小的组件,比如说电池,固定机身的螺丝钉等,我们还需要装配这些零件,这又是另一个步骤。
  • 再比如我们的神舟飞船,我们除了需要生产零件的厂商将零件送过来,我们还需要在一个地方将这些零件按照步骤装配起来。
  • 注意,实际开发中,建造者模式一般会和工厂模式搭配起来使用。因为你要建某个零件,这些零件来自于工厂(工厂模式),建造者调用工厂建好这些零件,然后拿过来装配。所以,这些模式经常互相搭配。

​ 实际开发中,建造者模式通常用来构建复杂的对象。说白了也就是建造者类负责对象的创建和返回,返回的对象由组建者进行拼装。

2. 建造者模式的本质

  • 分离了对象子组件单独构建(由 Builder 来负责)和装配(由 Director 负责)。从而可以构造出复杂的对象。这个模式适用于:某个对象的构建过程复杂的情况下使用。

  • 由于实现了构建和装配的解耦。不同的构建器,相同的装配,可以做出不同的对象;相同的构建器,不同的装配顺序也可以做出不同的对象。也就是实现了构建算法、装配算的解耦,实现了更好的复用。

    • 比如之前的造汽车,低级的轮胎,低级的底盘,低级的发动机等等,通过汽车装配,可以产出一辆低端汽车;同样的,我们使用高级的轮胎,高级的底盘,高级的发动机等等,通过汽车装配,我们可以产出一辆高级的汽车。这个就是不同的构建器,相同的装配产出不同的对象。
    • 反过来,相同的构建起,不同的装配顺序也可以做出不同的对象。比如搭积木,构建的时候构建了一个矩形,一个小圈。不同的组装顺序出来的结构不一样。比如小圈贴着矩形的宽和小圆贴着矩形的长。

3. 例子

3.1 类的类图 - 创建飞船:

在这里插入图片描述

​ 一个飞船类,里面有三个方法:轨道舱,引擎,逃逸塔。一个飞船有这样三个零件。

​ 有这样的一个借口:ArishipBuilder 用来构建我们的各个组件。

​ 还有一个 Director 类,负责装配。在后面的代码实现中,我们将其搞成接口,并创建实现类。这样的就有不同的装配者了。它负责调用 Builder 中的内容,然后再进行组装。最后组装出来一个新的产品。

​ 在后来的调用中,客户端 Client 调用特定的装配者,告诉程序我们要组装一个什么样的产品。然后装配者和建造者打交道,建造者负责调用构造者生产零件,然后装配者负责装配。所以客户端只需要和建造者打交道,其他的在后台由建造者去和其他的类和接口进行沟通。

​ 建造者内部的方法还可以调用工厂模式,从工厂中取出零件,这样就和工厂模式搭配起来了。

3.2 代码的实现

  • 首先创建我们的实体类 - AirShip 类,在它之下有它需要的组件:

    /**
     * 宇宙飞船
     */
    
    public class AirShip {
    
        private OrbitalModule obritalModule; // 轨道舱发
        private Engine engine; // 发动机
        private EscapeTower escapeTower; // 逃逸仓
    
    
        public OrbitalModule getObritalModule() {
            return obritalModule;
        }
    
        public void setObritalModule(OrbitalModule obritalModule) {
            this.obritalModule = obritalModule;
        }
    
        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) {
            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) {
            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) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
  • 然后创建建造者接口,用于规范后面的实现类:

    public interface AirShipBuilder {
    
        Engine builderEngine();
        OrbitalModule buildOrbitalModule();
        EscapeTower escapeTower();
    
    }
    

    它里面有三个方法,分别是建造引擎,轨道舱和逃逸塔

  • 然后创建我们的组装者接口,用于规范后面的组装者的实现类:

    public interface AirShipDirector {
    
        /**
         * 组装飞船
         * @return AirShip
         */
        AirShip directorAirShip();
    
    }
    
    

    它就一个方法,组装我们的飞船。

  • 然后创建建造者的实现类,SxtAirShipBuilder类:

    // StringBuilder, DomBuild, DOMBuilder, SaxBuilder 都是这个模式
    public class SxtAirShipBuilder implements AirShipBuilder {
        @Override
        public Engine builderEngine() {
            System.out.println("构建发动机");
            return new Engine("发动机");
        }
    
        @Override
        public OrbitalModule buildOrbitalModule() {
            System.out.println("构建轨道舱");
            return new OrbitalModule("轨道舱");
        }
    
        @Override
        public EscapeTower escapeTower() {
            System.out.println("构建逃逸塔");
            return new EscapeTower("逃逸塔");
        }
    
    }
    

    这个类我们通过调用不同的构建者,构建不同的对象,然后返回,供组装者组装调用。

  • 然后创建我们的组装者类,SxtAirShipDirector类:

    public class SxtAirShipDirector implements AirShipDirector {
    
        private AirShipBuilder builder;
    
        public SxtAirShipDirector(AirShipBuilder builder) {
            this.builder = builder;
        }
    
        @Override
        public AirShip directorAirShip() {
            Engine engine = builder.builderEngine();
            OrbitalModule orbitalModule = builder.buildOrbitalModule();
            EscapeTower escapeTower = builder.escapeTower();
            // 进行组装
            AirShip ship = new AirShip();
            ship.setEngine(engine);
            ship.setObritalModule(orbitalModule);
            ship.setEscapeTower(escapeTower);
    
            return ship;
        }
    }
    

    组装者内部创建一个建造者对象,用于调用建造者去建造组件,以供自己的组件产品使用。

  • 最后,就是我们的客户端类了。

    public class Client {
        public static void main(String[] args) {
            AirShipDirector airShipDirector = new SxtAirShipDirector(new SxtAirShipBuilder());
            AirShip airShip = airShipDirector.directorAirShip();
            System.out.println(airShip.getEngine().getName());
            airShip.launch();
        }
    
    }
    

    我们的客户端类只需要和 Director的实现类打交道就可以了。

4. 建造者模式开发的应用场景

  • 开发中的应用场景:
    • StringBuilder 类的 append 方法
    • SQL中的 PreparedStatement 方法
    • JDOM 中, DomBuilder、SAXBuilder
  • 当然我们在自己开发项目的时候,用到建造者模式的情况并不多见。除非去开发一个产品,这是有可能的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值