首页 > 其他分享 >设计模式-建造者模式

设计模式-建造者模式

时间:2024-04-07 14:33:25浏览次数:16  
标签:对象 创建 void 建造 模式 Override 设计模式 public

1. 概念

  • 建造者模式(Builder Pattern)又叫生成器模式,是一种创建型设计模式,用于将复杂对象的构建过程与其表示分离,以便相同的构建过程可以创建不同的表示。这种模式特别适用于创建那些具有多个组成部分、步骤复杂或者产品具有多种不同变化的对象。

2. 原理结构图

在这里插入图片描述

  • 原理结构图说明
    • 产品(Product):这是最终要创建的复杂对象,它由多个部件组成,这些部件可能有不同的创建和组装过程。
    • 抽象建造者(Builder):这个角色定义了创建产品对象的各个部件所需的抽象接口。通常会声明两类方法,一类是buildXXX()方法,用于创建复杂对象的各个部分;另一类是getResult()方法,用于返回最终的复杂对象。
    • 具体建造者(ConcreteBuilder):这个角色实现了抽象建造者的接口或继承了抽象建造者的类。它负责实现各个部件的具体构造和装配方法,并定义所创建的复杂对象。具体建造者还可能提供一个方法来返回创建好的复杂对象。
    • 指挥者(Director):这个角色负责按照特定的顺序调用具体建造者的方法来构建产品。指挥者知道如何组织和协调各个部件的构建过程,以确保按照正确的顺序完成。

3. 代码示例

3.1 示例1
  • 建造者模式代码示例
/**
 * 产品类
 */
class Product {
    private String partA;
    private String partB;

    public void setPartA(String partA) {
        this.partA = partA;
    }

    public void setPartB(String partB) {
        this.partB = partB;
    }

    public void show() {
        System.out.println("Product: " + partA + ", " + partB);
    }
}

/**
 * 抽象建造者
 */
abstract class Builder {
    protected Product product = new Product();

    public abstract void buildPartA();
    public abstract void buildPartB();
    public abstract Product getResult();
}

/**
 * 具体建造者
 */
class ConcreteBuilder extends Builder {
    @Override
    public void buildPartA() {
        product.setPartA("PartA");
    }

    @Override
    public void buildPartB() {
        product.setPartB("PartB");
    }

    @Override
    public Product getResult() {
        return product;
    }
}

// 指挥者
class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public Product construct() {
        builder.buildPartA();
        builder.buildPartB();
        return builder.getResult();
    }
}

/**
 * 客户端代码
 */
public class Client {
    public static void main(String[] args) {
        Builder builder = new ConcreteBuilder();
        Director director = new Director(builder);
        Product product = director.construct();
        product.show();
    }
}

3.2 示例二
  • 实例代码
class MilkTea {
    double price;
    String topping = "cream";
    String tea = "Common tea";
    Integer suger = 100;

    public MilkTea() {
        this.price = 9.9;
    }

    public double getPrice() {
        return this.price;
    }
}

class LatteMilkTea extends MilkTea {
    public LatteMilkTea() {
        this.price = 10.9;
    }
}

class IceCreamMilkTea extends MilkTea {
    public IceCreamMilkTea() {
        this.price = 11.9;
    }
}

interface MilkteaBuilder {
    void reset();

    void addTopping();

    void addTea();

    void addSugerLevel();

    MilkTea getProduct();
}

class LatteMilkTeaBuilder implements MilkteaBuilder {

    private LatteMilkTea latteMilkTea;

    @Override
    public void reset() {
        this.latteMilkTea = new LatteMilkTea();
    }

    @Override
    public void addTopping() {
        latteMilkTea.topping = "latte topping";
    }

    @Override
    public void addTea() {
        latteMilkTea.tea = "latte tea";
    }

    @Override
    public void addSugerLevel() {
        latteMilkTea.suger = 95;
    }

    @Override
    public MilkTea getProduct() {
        System.out.format("LatteMilkTea: %s %s %s\n", this.latteMilkTea.topping, this.latteMilkTea.tea, this.latteMilkTea.price);
        return this.latteMilkTea;
    }
}

class IceCreamMilkTeaBuilder implements MilkteaBuilder {

    private IceCreamMilkTea iceCreamMilkTea;

    @Override
    public void reset() {
        this.iceCreamMilkTea = new IceCreamMilkTea();
    }

    @Override
    public void addTopping() {
        iceCreamMilkTea.topping = "ice cream topping";
    }

    @Override
    public void addTea() {
        iceCreamMilkTea.tea = "ice cream tea";
    }

    @Override
    public void addSugerLevel() {
        iceCreamMilkTea.suger = 95;
    }

    @Override
    public MilkTea getProduct() {
        System.out.format("LatteMilkTea: %s %s %s\n", this.iceCreamMilkTea.topping, this.iceCreamMilkTea.tea, this.iceCreamMilkTea.price);
        return this.iceCreamMilkTea;
    }
}

class MilkTeaDirector {
    private MilkteaBuilder milkteaBuilder;

    public MilkTeaDirector(MilkteaBuilder milkteaBuilder) {
        this.milkteaBuilder = milkteaBuilder;
    }

    public void changeBuiler(MilkteaBuilder milkteaBuilder) {
        this.milkteaBuilder = milkteaBuilder;
    }

    public MilkTea makeMikeTea() {
        this.milkteaBuilder.reset();
        this.milkteaBuilder.addTopping();
        this.milkteaBuilder.addTea();
        this.milkteaBuilder.addSugerLevel();
        return this.milkteaBuilder.getProduct();
    }

    public MilkTea make(String type) {
        if ("Latte".equals(type)) {
            this.changeBuiler(new LatteMilkTeaBuilder());
        } else if ("IceCream".equals(type)) {
            this.changeBuiler(new IceCreamMilkTeaBuilder());
        }
        return this.makeMikeTea();
    }

}

public class MilkTeaShop {
    public static void main(String[] args) {
        MilkTeaDirector director = new MilkTeaDirector(new LatteMilkTeaBuilder());
        director.makeMikeTea();
        director.changeBuiler(new IceCreamMilkTeaBuilder());
        director.makeMikeTea();
        director.make("Latte");
        director.make("IceCream");
    }
}


4. 优缺点

  • 主要作用
    • 逐步创建复杂的对象
  • 优点
    • 封装性好:创建和使用分离,用户无需了解产品内部细节。
    • 扩展性好:由于建造类之间相互独立,在一定程度上实现了解耦,易于扩展和维护。
    • 创建复杂对象:能够创建由各种复杂部件组成的产品,对于构造过程复杂的对象尤为有用。
  • 缺点
    • 增加类数量:可能会产生多余的Builder对象,增加系统的复杂度。
    • 修改困难:当产品内部发生变化时,可能需要相应地修改建造者,维护成本较高。

5. 应用场景

  • 对象构造复杂:当一个对象有很多属性,且这些属性的设置和组合非常复杂时,可以使用建造者模式来简化对象的构建过程。
  • 参数过多:如果一个类的构造函数参数超过四个,特别是当某些参数是可选的或有默认值时,建造者模式可以帮助避免构造函数过于臃肿。
  • 分步创建:在需要分步骤创建复杂对象时,建造者模式可以将每一步创建过程封装在不同的方法中,使得创建过程更加清晰和灵活。
  • 创建与使用分离:当希望将复杂对象的创建过程和使用过程分开时,建造者模式可以很好地实现这一目标,提高代码的可维护性和扩展性。
  • 多种表示:如果同一个复杂对象有多种不同的表示或配置方式,建造者模式可以通过不同的构建过程来创建这些不同的表示。
  • 顺序敏感:当对象的构建过程中调用顺序不同可能导致不同的结果时,建造者模式可以通过指导者(Director)来控制构建顺序,确保对象的正确构建。

6. JDK中的使用

  • StringBuilder类:这是JDK中一个典型的建造者模式实现。通过连续调用append方法,我们可以链式地构建一个字符串对象。最终,通过调用toString方法,我们可以得到一个完整的字符串对象。
  • MyBatis中的SqlSessionFactoryBuilder:MyBatis是一个广泛使用的持久层框架,它的SqlSessionFactoryBuilder类也使用了建造者模式。这个类提供了一种逐步配置并最终构建SqlSessionFactory对象的方法。

7. 建造者 VS 抽象工厂

建造者抽象工厂
目的构建复杂对象创建一系列相关关联的对象
创建对象方式多步骤创建单一步骤创建

8. 注意事项

  • 明确需求:在实现建造者模式之前,需要明确复杂对象的构建需求。
  • 分清角色:清晰区分建造者、具体建造者、指挥者和产品的角色。
  • 构建解耦:确保构建过程与产品表示分离,使得同样的构建过程可以创建不同的表示。
  • 顺序重要:当产品的构建顺序很重要时,需要确保指挥者能够控制具体的构建步骤和顺序。
  • 避免过度设计:如果产品内部变化不复杂,不需要定义过多的具体建造者。

标签:对象,创建,void,建造,模式,Override,设计模式,public
From: https://blog.csdn.net/m0_51176516/article/details/137454537

相关文章

  • 设计模式 - 代理模式
    使用代理对象,我们可以对与某些对象的交互进行更多的控制。代理对象可以在我们与对象进行交互时确定其行为,例如,当我们获取值或设置值时。一般来说,代理是指代替他人的人。你不是直接和那个人说话,而是和代表你试图联系的人说话的代理。在JavaScript中也是如此:我们不是直接与目标......
  • C++设计模式:TemplateMethod模式(一)
    1、概念定义定义一个操作中的算法的骨架结构(稳定),而将一些步骤延迟(变化)到子类中。TemplateMethod使得子类可以不改变(复用)一个算法的骨架结构即可重定义(override重写)该算法的某些特定步骤在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但是各个子步骤却有很......
  • 折腾PXE网络启动 pxe 双引导bios&uefi模式 WDS windows deployment server
    简介:这才是最终章。折腾这么多,其实还是为了WDS。折腾TFTPD引导bios,是为了确认引导文件可以引导maxdos。折腾TFTPD引导uefi,也是为了确认可以引导grub。折腾OPENWRT双引导bios和UEFI,是为了确认DHCPoption93。现在我们有了可以双引导的TFTP-ROOT目录,虽然只有4个文件,这足够我......
  • 毅四捕Go设计模式笔记——桥接模式
    桥接模式(BridgePattern)桥接模式是一种结构型设计模式,它的主要目的是将抽象部分与它的实现部分解耦,使它们都可以独立的变化。通过使用组合而非继承的方式,桥接模式结合了两个独立的维度,让它们可以独立扩展而不是在两者之间建立静态的继承关系。为了解决什么问题?桥接模式解......
  • 折腾PXE网络启动 pxe 双引导bios&uefi模式 OPENWRT
    简介:前两篇已经折腾了pxe引导bios和uefi,甭管启动的是啥,已经可以网络引导了。但是同时面对这两种系统的时候怎么办?需要通过dhcp的参数来控制谁启动什么。核心内容RFC4578:DynamicHostConfigurationProtocol(DHCP)OptionsfortheIntelPrebooteXecutionEnvironment(......
  • 适配器模式
     1.介绍适配器模式将某个类的接口转换成客户端期望的另一个接口,用户调用适配器转换出来的目标接口方法,适配器再调用被适配者的相关接口方法; 2.实现方式(1)类适配器模式/***@Description:被适配类*@date:2024/4/615:56*/publicclassVoltage220V{......
  • 观察者模式与发布-订阅模式的对决
    ......
  • Photoshop混合模式的底层原理
        Photoshop虽然不是什么高手,但平时工作中难免会用到,处理部分需求还是可以胜任的。接触PS这么多年,对PS中图层的混合模式(BlendMode)一直就处于懵懂状态,即使是看了教材及视频后,有了一点感性认识,但在实际操作中仍旧无法运用起来。直至某一天,我在B站看到韩世麟的《把PS......
  • 常用软件架构模式优缺点及应用场景
     1、分层架构模式最常见的架构模式就是分层架构或者称为n层架构。大部分软件架构师、设计师和开发者都对这个架构模式非常熟悉。尽管对于层的数量和类型没有具体限制,但大部分分层架构主要由四层组成:展现层、业务层、持久层和数据库层,如下图所示。一个很流行的n层架构示......
  • 建造者模式
     1.盖房子需求(1)建造房子需要打桩,砌墙,封顶;(2)房子有各种各样,如普通房子,高楼。 2.实现方式(1)传统方式/***@Description:传统方式*@date:2024/4/612:11*/publicabstractclassAbstractHouse{//打地基publicabstractvoidbuildBasic()......