二十三种设计模式------建造者模式

本文介绍了建造者模式的概念及其在房屋建造和麦当劳套餐定制中的应用。通过指挥者和具体建造者的角色,实现了构建过程的解耦和顺序控制。建造者模式的优势在于实现产品构建与表示的分离,简化复杂产品的创建步骤,并允许灵活扩展。然而,当产品差异性较大时,建造者模式可能不适用,且过多的建造者可能导致系统复杂度增加。
摘要由CSDN通过智能技术生成

原文链接:二十三种设计模式——建造者模式 – 编程屋

1 前言

        建造者模式属于建造者模式,它提供了一种创建对象的最佳方式。

在不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象,用户只需要给出指定复杂对象和内容,建造者模式按照顺序创建复杂对象。

既然是建造者模式。那么我们就用建造房屋来举例。假设我们建造房屋有4个步骤:

(1 )房屋设计  (2)  建造地基 (3) 铺设管道 (4) 粉刷房屋

其中这4个步骤就是我们抽象的Builder(图中序号2)

然后我们需要找具体的建造者也就是工人去建造房屋(图中序号3)

其次我们需要一个指挥者去指挥工人按照什么样的顺序去建造房屋(图中序号1)

最后生产出我们具体的产品(图中序号4)        

 2 Builder模式实现

        2.1 Builder模式的常规实现

步骤一:创建抽象类(建造房屋的具体方法)

//建造者抽象的建造方法
public abstract class Builder {

    abstract void builderA();  //地基
    abstract void builderB();  //钢筋工程
    abstract void builderC();  //铺设电线
    abstract void builderD();  //粉刷


    //完工 得到具体的产品
    abstract Product getProduct();

    
}

步骤二:创建产品类(具体的产品)

// 建造的产品
public class Product {

    private String buildA;

    private String buildB;

    private String buildC;

    private String buildD;

    public String getBuildA() {
        return buildA;
    }

    public void setBuildA(String buildA) {
        this.buildA = buildA;
    }

    public String getBuildB() {
        return buildB;
    }

    public void setBuildB(String buildB) {
        this.buildB = buildB;
    }

    public String getBuildC() {
        return buildC;
    }

    public void setBuildC(String buildC) {
        this.buildC = buildC;
    }

    public String getBuildD() {
        return buildD;
    }

    public void setBuildD(String buildD) {
        this.buildD = buildD;
    }

    @Override
    public String toString() {
        return "Product{" +
                "buildA='" + buildA + '\'' +
                ", buildB='" + buildB + '\'' +
                ", buildC='" + buildC + '\'' +
                ", buildD='" + buildD + '\'' +
                '}';
    }
}

步骤三: 创建具体的builder(具体实施产品的类)

//具体的建造者
public class Wroker extends Builder{

     private Product product;

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

    @Override
    void builderA() {
        product.setBuildA("地基");
        System.out.println("地基");
    }

    @Override
    void builderB() {
        product.setBuildB("钢筋工程");
        System.out.println("钢筋工程");
    }

    @Override
    void builderC() {
        product.setBuildC("铺设电线");
        System.out.println("铺设电线");
    }

    @Override
    void builderD() {
        product.setBuildD("粉刷房屋");
        System.out.println("粉刷房屋");
    }

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

步骤四: 创建指挥者(面向抽象类)

//指挥者 指挥工人构建工程
public class Director {

    //指挥工人按照顺序建造房子
    public Product build(Builder builder){
        builder.builderA();
        builder.builderB();
        builder.builderD();
        builder.builderC();

        return builder.getProduct();

    }
}

步骤五:测试

public class Test {
    public static void main(String[] args) {
        Director director = new Director();
        Product build = director.build(new Wroker());
        System.out.println(build.toString());
    }
}

 测试结果:

上面的示例是Builder的常规用法,导演类Director在建造者模式中具有十分重要的作用,它用于指导构建者如何构建出产品。我们只需要控制工人来控制调用的先后顺序.向调用者返回一个完整的产品

2.2 Builder模式通过静态内部类实现

        此次的实现方式我们省去指挥者这个角色。我们举个去吃麦当劳的例子。我们去吃麦当劳可以选择许多套餐。可以自己选择,同时也可以选择系统默认的套餐。

步骤一:创建一个Builder抽象类(选择套餐)

public abstract class Builder {

    abstract Builder builderA(String msg);  //汉堡
    abstract Builder builderB(String msg);  //炸鸡
    abstract Builder builderC(String msg);  //可乐
    abstract Builder builderD(String msg);  //薯片


    //完工 得到具体的产品
    abstract Product getProduct();


}

步骤二:创建一个产品类(有默认套餐)

public class Product {

    //默认套餐
    private String BuilderA = "汉堡";
    private String BuilderB = "炸鸡";
    private String BuilderC = "可乐";
    private String BuilderD = "薯片";

    public String getBuilderA() {
        return BuilderA;
    }

    public void setBuilderA(String builderA) {
        BuilderA = builderA;
    }

    public String getBuilderB() {
        return BuilderB;
    }

    public void setBuilderB(String builderB) {
        BuilderB = builderB;
    }

    public String getBuilderC() {
        return BuilderC;
    }

    public void setBuilderC(String builderC) {
        BuilderC = builderC;
    }

    public String getBuilderD() {
        return BuilderD;
    }

    public void setBuilderD(String builderD) {
        BuilderD = builderD;
    }

    @Override
    public String toString() {
        return "Product{" +
                "BuilderA='" + BuilderA + '\'' +
                ", BuilderB='" + BuilderB + '\'' +
                ", BuilderC='" + BuilderC + '\'' +
                ", BuilderD='" + BuilderD + '\'' +
                '}';
    }
}

步骤三:  创建一个实现Builder抽象类具体建造者

public class Wroker extends Builder {

    private Product product;

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


    @Override
    Builder builderA(String msg) {
        product.setBuilderA(msg);
        return this;
    }

    @Override
    Builder builderB(String msg) {
        product.setBuilderB(msg);
        return this;
    }

    @Override
    Builder builderC(String msg) {
        product.setBuilderC(msg);
        return this;
    }

    @Override
    Builder builderD(String msg) {
        product.setBuilderD(msg);
        return this;
    }

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

步骤四:测试

public class Test {
    public static void main(String[] args) {
        Wroker wroker = new Wroker();
        Product product = wroker.builderA("香辣鸡腿堡")
                .getProduct();
        System.out.println(product.toString());
    }
}

测试结果:

我们可以发现。这种方式较上一种方式更为的方便简单,可以还可以灵活的调用 

建造者模式优点:

        产品的建造和表示分离,实现了解耦。使用了建造者模式可以使客户端不必知道产品内部组成的细节

        将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰

        具体建造者之间是相互独立的,这有利于系统的拓展。增加新的具体建造者无需修改原有类库的代码,符合开闭原则

 建造者模式缺点:

        建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则适合使用建造者模式,因此其使用范围受到一定限制

        如果产品内部变化复杂,可能会导致需要定义很多具体建造者来实现这种变化,导致系统变的很庞大。

以上只是部分内容,为了维护方便,本文已迁移到新地址:二十三种设计模式——建造者模式 – 编程屋

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值