设计模式之建造者模式

  • 建造者模式也属于创建型模式,它提供了一种创建对象的最佳方式。
  • 定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
  • 主要作用:在用户 不知道对象的建造过程和细节的情况下 就可以直接创建复杂的对象
  • 用户只需要给出指定复杂对象的类型和内容,建造者模式负责按顺序创建复杂对象(把内部的建造过程和细
    节隐藏起来)
  • 例子:
    • 工厂(建造者模式) :负责制造汽车(组装过>程和细节在工厂内)
    • 汽车购买者(用户) :你只需要说出你需要的>型号(对象的类型和内容),然后直接购买就可以使用了(不需要知道汽车是怎么组装的(车轮、车门、>发动机、 方向盘等等) )

建造者模式的常规用法

案例:

  • 既然是建造者模式,那么我们还是继续造房吧,其实我也想不到更简单的例子。假设造房简化为如下步骤:
    (1) 地基(2)钢筋工程(3) 铺电线(4) 粉刷; "如果"要盖一座房子,首先要找一个建筑公司或工程承包商(指挥者)。承包商指挥工人(具体建造者)过来造房子(产品),最后验收。

  • 角色分析:

    在这里插入图片描述

  • 代码:

package com.wlw.builder;

//建造者的抽象方法,来指明具体的建造者要完成哪些任务(方法)
public abstract class Builder {
    abstract void buildA();//地基
    abstract void buildB();//钢筋工程
    abstract void buildC();//电线
    abstract void buildD();//粉刷

    //完工,得到产品
    abstract Product getProduct();
}

package com.wlw.builder;

//产品,房子,  一个产品是需要工人通过具体的流程任务来完成建造的
public class Product {
    private String buildA;
    private String buildB;
    private String buildC;
    private String buildD;
	
    //get set toString 方法省略....
}

package com.wlw.builder;

//具体的建造者:工人。 建造一个房子,对于一个房子来说,工人完成这些任务之后自然一个房子就完成了
public class Worker extends Builder {

    private Product product;
    //工人负责创建产品
    public Worker() {
        product = new Product();
    }

    @Override
    void buildA() {
        System.out.println("第一步,地基");
        product.setBuildA("第一步,地基");
    }

    @Override
    void buildB() {
        System.out.println("第二步,钢筋工程");
        product.setBuildB("第二步,钢筋工程");
    }

    @Override
    void buildC() {
        System.out.println("第三步,电线");
        product.setBuildC("第三步,电线");
    }

    @Override
    void buildD() {
        System.out.println("第四步,粉刷");
        product.setBuildD("第四步,粉刷");
    }

    @Override
    Product getProduct() {
        return product;
    }

}

package com.wlw.builder;

//指挥者(核心),指挥具体的工人完成任务,具体怎样完成都是指挥者来决定的
public class Director {

    //指挥具体的工人完成任务,具体的任务执行顺序可以自己决定
    public Product build(Builder builder){
        builder.buildA();
        builder.buildB();
        builder.buildC();
        builder.buildD();

        return builder.getProduct();
    }
}
package com.wlw.builder;

public class Test {
    public static void main(String[] args) {
        //指挥者
        Director director = new Director();
        //指挥工人建造房子,得到产品
        Product product = director.build(new Worker());
        System.out.println(product.toString());
    }
}
/*
第一步,地基
第二步,钢筋工程
第三步,电线
第四步,粉刷
Product{buildA='第一步,地基', buildB='第二步,钢筋工程', buildC='第三步,电线', buildD='第四步,粉刷'}
*/
  • 上面示例是 Builder模式的常规用法,导演类Director 在Builder模式中具有很重要的作用,它用于指导具体构建者如何构建产品,控制调用先后次序,并向调用者返回完整的产品类,但是有些情况下需要简化系统结构,可以把Director和抽象建造者进行结合。
  • 通过静态内部类方式实现零件无序装配构造, 这种方式使用更加灵活,更符合定义。内部有复杂对象的默认实现,使用时可以根据用户需求自由定义更改内容,并且无需改变具体的构造方式。就可以生产出不同复杂产品。
  • 比如:比如麦当劳的套餐,服务员(具体建造者)可以随意搭配任意几种产品(零件)组成一款套餐(产品),然后出售给客户。比第一种方式少了指挥者,主要是因为第二种方式把指挥者交给用户来操作,使得产品的创建更加简单灵活。(让客户取代指挥者)

建造者模式的第二种方式

package com.wlw.builder.demo02;

//建造者的抽象
public abstract class Builder {
    abstract Builder buildA(String msg);
    abstract Builder buildB(String msg);
    abstract Builder buildC(String msg);
    abstract Builder buildD(String msg);

    abstract Product getProduct();
}

package com.wlw.builder.demo02;

//产品(套餐)
public class Product {
    private String buildA = "汉堡";
    private String buildB = "可乐";
    private String buildC = "鸡翅";
    private String buildD = "土豆泥";

	//set get toString 省略.....
}

package com.wlw.builder.demo02;

//具体的实施者(服务员,客户等)
public class Worker extends Builder {
    private Product product;

    public Worker() {
        product = new Product();
    }

    @Override
    Builder buildA(String msg) {
        product.setBuildA(msg);
        return this;
    }

    @Override
    Builder buildB(String msg) {
        product.setBuildB(msg);
        return this;
    }

    @Override
    Builder buildC(String msg) {
        product.setBuildC(msg);
        return this;
    }

    @Override
    Builder buildD(String msg) {
        product.setBuildD(msg);
        return this;
    }

    @Override
    Product getProduct() {
        return product;
    }
}

package com.wlw.builder.demo02;

public class Test {
    public static void main(String[] args) {
        //服务员(客户)
        Worker worker = new Worker();

        //Product product = worker.getProduct();
        //System.out.println(product.toString()); //输出默认的套餐
        //Product{buildA='汉堡', buildB='可乐', buildC='鸡翅', buildD='土豆泥'}

        //链式编程,在原来的基础上,可以自由组合了,如果不组合,也有默认的套餐
        Product product = worker.buildB("雪碧").getProduct(); 
        System.out.println(product.toString()); //输出自定义的
        //Product{buildA='汉堡', buildB='雪碧', buildC='鸡翅', buildD='土豆泥'}
    }
}

建造者模式总结

  • 优点:

    • 产品的建造和表示分离,实现了解耦。使用建造者模式可以使客户端不必知道产品内部组成的细节。
    • 将复杂产品的创建步骤分解在不同的方法中, 使得创建过程更加清晰
    • 具体的建造者类之间是相互独立的,这有利于系统的扩展。增加新的具体建造者无需修改原有类库的
      代码,符合"开闭原则”。
  • 缺点:

    • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则
      不适合使用建造者模式,因此其使用范围受到一定的限制。
    • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很
      庞大。
  • 应用场景:

    • 需要生成的产品对象有复杂的内部结构,这些产品对象具备共性;
    • 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。
    • 适合于一个具有较多的零件(属性)的产品(对象)的创建过程。
  • 建造者与抽象工厂模式的比较:

    • 与抽象工厂模式相比,建造者模式返回一个组装好的完整产品,而抽象工厂模式返回一系列相关的产
      品,这些产品位于不同的产品等级结构,构成了一个产品族。
    • 在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,
      客户端可以不直接调用建造者的相关方法,而是通过指挥者类来指导如何生成对象,包括对象的组装
      过程和建造步骤,它侧重于一步步构造一 一个复杂对象,返回-个完整的对象。
    • 如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车
      组装工厂,通过对部件的组装可以返回一辆完整的汽车!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悬浮海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值