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

设计模式[4]-建造者模式

时间:2024-08-23 11:04:55浏览次数:8  
标签:liquid Builder Beverage 建造 模式 label beverage 设计模式 public

代码:https://gitee.com/Aes_yt/design-pattern

建造者模式

建造者模式是将一个复杂对象,解构为多个简单的对象,然后一步一步慢慢构造成原对象。

建造者模式主要包括四种角色:
  • 抽象建造者:具有产品的多个子部件的抽象接口,最终可以返回完整产品
  • 具体建造者:对抽象建造者的实现,有多个子部件的具体生成方法
  • 产品角色:一个复杂对象,由建造者来构造它的不同子部件。
  • 指挥者:调用建造者对产品子部件的构建,可以决定创建子部件的顺序
例子

如果我们要创建一个产品角色:一瓶瓶装饮料,它是由瓶身,液体,商标组成,现在我们要创建一瓶可乐饮料和一瓶雪碧饮料,那么我们就可以用建造者模式来实现这个需求。

  • 抽象建造者:Builder,拥有构造产品角色部件的三个方法和返回完整Beverage 对象的方法。
  • 具体建造者:ColaBuilder和SpriteBuilder,各自实现Builder的方法。
  • 产品角色:Beverage 饮料类,包含bottler,liquid,label对象。
  • 指挥者:Director,装载不同Builder,按一定顺序创建bottler,liquid,label对象,最终返回完整Beverage对象。

image-20211216233023185

产品角色:饮料类:Beverage

@Data
public class Beverage {
    private String bottle;
    private String liquid;
    private String label;

    @Override
    public String toString() {
        return "Beverage{" +
                "bottle='" + bottle + '\'' +
                ", liquid='" + liquid + '\'' +
                ", label='" + label + '\'' +
                '}';
    }
}

抽象建造者:Builder:

public abstract class Builder {
    protected Beverage beverage = new Beverage();

    /**
     * 构建瓶子对象
     */
    abstract void builderBottle();

    /**
     * 构建液体对象
     */
    abstract void builderLiquid();

    /**
     * 构建商标对象
     */
    abstract void builderLabel();

    /**
     * 构建饮料对象
     */
    abstract Beverage build();
}

具体建造者:

每种具体产品都实现具体的建造者。

可乐建造者:ColaBuilder:

public class ColaBuilder extends Builder {
    @Override
    public void builderBottle() {
        beverage.setBottle("透明瓶子");
    }

    @Override
    public void builderLiquid() {
        beverage.setLiquid("黑色汽水");
    }

    @Override
    public void builderLabel() {
        beverage.setLabel("Cola~");
    }

    @Override
    public Beverage build() {
        return beverage;
    }
}

雪碧建造者:SpriteBuilder:

public class SpriteBuilder extends Builder{
    @Override
    public void builderBottle() {
        beverage.setBottle("绿色瓶子");
    }

    @Override
    public void builderLiquid() {
        beverage.setLiquid("白色汽水");
    }

    @Override
    public void builderLabel() {
        beverage.setLabel("Sprite~");
    }

    @Override
    public Beverage build() {
        return beverage;
    }
}

指挥者:Director:

public class Director {
    private Builder builder;

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

    /**
     * 指挥者决定构造的顺序,最后返回完整的对象
     */
    public Beverage construct() {
        this.builder.builderBottle();
        this.builder.builderLiquid();
        this.builder.builderLabel();
        return this.builder.build();
    }
}

测试:

class DirectorTest {
    @Test
    void construct() {
        Director director = new Director(new ColaBuilder());
        Beverage beverage = director.construct();
        System.out.println(beverage);

        director = new Director(new SpriteBuilder());
        beverage = director.construct();
        System.out.println(beverage);
    }
}

输出:

Beverage{bottle='透明瓶子', liquid='黑色汽水', label='Cola~'}
Beverage{bottle='绿色瓶子', liquid='白色汽水', label='Sprite~'}
分析

建造者模式可以对子部件的模块的创建进行控制,最终再获得完整的产品。这和工厂模式的侧重点不同,工厂模式注重完整对象的创建过程,建造者模式注重零件的组装过程。而且建造者可以在指挥者角色中控制子部件的组装顺序,顺序不同,最终组装的产品也有可以不同,这也是它的特点。

拓展

用建造者模式实现链式赋值:

以上面的例子Beverage为例,如果我们想直接新建一个Beverage实例并给他赋值,我们的代码应该是:

    void test() {
        Beverage beverage = new Beverage();
        beverage.setLabel("标签");
        beverage.setLiquid("液体");
        beverage.setBottle("瓶子");
        System.out.println(beverage);
    }

接下来,我们利用建造者模式实现链式赋值。

我重新建了一个BeverageChain类来展示这个效果。

首先先去掉三个属性的get和set方法,然后创建私有的构造方法,接收的参数就是建造者对象,最后创建一个内部类当作建造者,用来建造三个参数,为了使用方便,变量名和方法名都是用同样的单词,最后在build方法,创建一个BeverageChain类返回完成建造。

public class BeverageChain {
    private String bottle;
    private String liquid;
    private String label;

    private BeverageChain(Builder builder) {
        this.bottle = builder.bottle;
        this.liquid = builder.liquid;
        this.label = builder.label;
    }

    @Override
    public String toString() {
        return "BeverageChain{" +
                "bottle='" + bottle + '\'' +
                ", liquid='" + liquid + '\'' +
                ", label='" + label + '\'' +
                '}';
    }

    public static class Builder {
        private String bottle;
        private String liquid;
        private String label;

        public Builder() {
        }

        public Builder bottle(String bottle) {
            this.bottle = bottle;
            return this;
        }

        public Builder liquid(String liquid) {
            this.liquid = liquid;
            return this;
        }

        public Builder label(String label) {
            this.label = label;
            return this;
        }

        public BeverageChain build() {
            return new BeverageChain(this);
        }
    }
}

测试:

@Test
void chained() {
    BeverageChain.Builder builder = new BeverageChain.Builder();
    BeverageChain beverage =  builder.bottle("瓶子").label("标签").liquid("液体").build();
    System.out.println(beverage);
}

输出:

BeverageChain{bottle='瓶子', liquid='液体', label='标签'}

标签:liquid,Builder,Beverage,建造,模式,label,beverage,设计模式,public
From: https://www.cnblogs.com/Aeons/p/18375611

相关文章

  • 设计模式[3]-原型模式
    代码:https://gitee.com/Aes_yt/design-pattern原型模式概念原型模式将一个已经创建的实例作为原型,复制出一个和原型相同的新对象。包括三种角色:抽象原型:抽象角色,提供具体原型需要实现的接口具体原型:被复制的对象,实现抽象原型的接口客户端:发出创建对象的请求。例子:先......
  • 设计模式[2]-工厂模式
    代码:https://gitee.com/Aes_yt/design-pattern工厂模式1.简单工厂模式简单工厂模式主要包括三种角色:简单工厂:创建具体产品抽象产品:具体产品的父类具体产品:简单工厂创建的对象例子:设计一个游戏机类(GameConsole)作为抽象产品,然后设计具体的产品(PlanStation4,Xb......
  • 设计模式[1]-单例模式
    代码:https://gitee.com/Aes_yt/design-pattern单例模式单例模式(Singleton)是一种创建型设计模式,能够保证一个类只有一个实例,并提供了访问该实例的全局节点。单例的实现步骤有以下步骤,首先将默认构造函数设置为私有,然后创建一个静态方法来调用私有构造函数来创建对象。单例类......
  • Scratch编程环境的暗色模式:探索可访问性的边界
    标题:Scratch编程环境的暗色模式:探索可访问性的边界Scratch,这个广受欢迎的图形化编程平台,由麻省理工学院媒体实验室开发,一直致力于为用户提供友好且易于访问的编程体验。随着用户对编程环境个性化需求的增长,Scratch的编程环境是否支持暗模式或可访问性选项,成为了编程教育领......
  • C++设计模式1:单例模式(懒汉模式和饿汉模式,以及多线程问题处理)
    饿汉单例模式        程序还没有主动获取实例对象,该对象就产生了,也就是程序刚开始运行,这个对象就已经初始化了。 classSingleton{public: ~Singleton() { std::cout<<"~Singleton()"<<std::endl; } staticSingleton*get_instance() { return&sin......
  • 火影忍者2——漩涡鸣人(仙人模式)篇
    老规矩,谈火影~火影忍者之——漩涡鸣人(仙人模式)篇众所周知,鸣仙是一个早期的A忍,技能破坏力贼大,一般遇到鸣仙(除非我用了青水+神卡)我是直接退的普攻一技能螺旋丸普通状态下一技能长摁放出两个分身释放螺旋丸,属于远程技能,但释放时的施法动作容易被打断,点击是本体出去,......
  • Java设计模式之代理模式:静态代理VS动态代理,与其他模式的对比分析和案例解析
    一、代理模式简介代理模式(ProxyPattern)是一种结构型设计模式,它提供了一个代理对象,用来控制对另一个对象的访问。这种模式通常用于在访问对象时引入额外的功能,而不改变对象的接口。代理模式的核心思想是为其他对象提供一种代理,以控制对这个对象的访问。在现实生活中,代理模......
  • 设计模式之责任链模式
    责任链模式是面向对象的23种设计模式中的一种,属于行为模式范围。责任链模式(ChainofResponsibility),见名知意:就是每一个处理请求的处理器组合成一个链表,链表中的每个节点(执行器)都有机会处理发送的请求。大致的结构是这个样子: 举一个简单的例子:某公司有一名新员工要入职,则入职......
  • Flannel Wireguard 模式
    FlannelWireGuard模式一、环境信息主机IPubuntu172.16.94.141软件版本docker26.1.4helmv3.15.0-rc.2kind0.18.0clab0.54.2kubernetes1.23.4ubuntuosUbuntu20.04.6LTSkernel5.11.5内核升级文档二、安装服务kind配置......
  • Flannel IPsec 模式
    FlannelIPSec模式一、环境信息主机IPubuntu172.16.94.141软件版本docker26.1.4helmv3.15.0-rc.2kind0.18.0clab0.54.2kubernetes1.23.4ubuntuosUbuntu20.04.6LTSkernel5.11.5内核升级文档二、安装服务kind配置文件......