设计模式系列----建造者模式理解

本文介绍了建造者模式的使用场景,当类的构造函数参数过多时,可考虑使用建造者模式。通过实例展示了如果不使用建造者模式,可能会导致过多的构造函数或者setter方法,不利于代码维护。在Java中,Lombok的@Builder注解简化了建造者模式的实现。文章还详细解释了传统建造者模式的四个角色,并提供了具体的代码示例。最后指出,虽然Lombok能简化构建过程,但理解建造者模式的思想仍然很重要。
摘要由CSDN通过智能技术生成

学习任何东西,都需要先知道使用场景,知道在哪里用,什么场景用,然后才是具体的学习,不然学了不会用就尴尬了

1、使用场景

当一个类的构造函数参数个数超过4个,而且这些参数有些是可选的参数,考虑使用构造者模式。

以上是使用场景,并且我们日常code过程中,也许就用到了建造者模式。比如在idea开发时,你开发的项目是否使用了lombok插件?这个插件相信从事Java的coder都不可避免的接触过。
lombok除了最基本的@Data注解,还有一个@Builder注解,这个注解就是lombok对建造者模式的封装,使用起来也非常的方便,如下:
在这里插入图片描述
在对应实体上面加上@Builder注解,当你想要对如上的UserVO实体进行构建时:

UserVO build = UserVO.builder().id(1L).userId(1234L).build();

如果属性再多一点,就更能体现builder的好处了,属于链式构建。

2、如果不使用建造者模式

第一,通过构造函数,如下:

public class Computer {
    
    public Computer(String cpu, String ram) {
        this(cpu, ram, 0);
    }
    public Computer(String cpu, String ram, int usbCount) {
        this(cpu, ram, usbCount, "罗技键盘");
    }
    public Computer(String cpu, String ram, int usbCount, String keyboard) {
        this(cpu, ram, usbCount, keyboard, "三星显示器");
    }
    public Computer(String cpu, String ram, int usbCount, String keyboard, String display) {
        this.cpu = cpu;
        this.ram = ram;
        this.usbCount = usbCount;
        this.keyboard = keyboard;
        this.display = display;
    }
}

这种构造器在各类源码中都是随处可见的,但这是为了方便我们使用者,在实际开发中,创建这么多构造器要累死。

2、使用getter、setter方法

public class Computer {
        ...

    public String getCpu() {
        return cpu;
    }
    public void setCpu(String cpu) {
        this.cpu = cpu;
    }
    public String getRam() {
        return ram;
    }
    public void setRam(String ram) {
        this.ram = ram;
    }
    public int getUsbCount() {
        return usbCount;
    }
...
}

这应该是我们在日常开发中最常用的了,但是他也有缺点,因为那个类中的属性是分步设置的,所以就容易出错。比如创建了一个实例,在方法中的第10行set了一个属性,然后在第70行又set了一个属性,一个对象的构建横跨几十行,这对于后面的维护者是非常的不友好的,这是其一。其二就是set一个属性就需要一行,后面属性多了,为了给一个实例赋值就用了几十行,太难看了。

传统的Builder模式

构建者模式UML图如下所示
在这里插入图片描述

如上图所示,builder模式有4个角色。

Product: 最终要生成的对象,例如 Computer实例。
Builder: 构建者的抽象基类(有时会使用接口代替)。其定义了构建Product的抽象步骤,其实体类需要实现这些步骤。其会包含一个用来返回最终产品的方法Product getProduct()。
ConcreteBuilder: Builder的实现类。
Director: 决定如何构建最终产品的算法. 其会包含一个负责组装的方法void Construct(Builder builder), 在这个方法中通过调用builder的方法,就可以设置builder,等设置完成后,就可以通过builder的 getProduct() 方法获得最终的产品。

如果很不幸,你的项目由于各种原因无法使用lombok插件,又想要使用建造者模式,我们来看看例子:
第一步:我们的目标Computer类:

public class Computer {
    private String cpu;//必须
    private String ram;//必须
    private int usbCount;//可选
    private String keyboard;//可选
    private String display;//可选

    public Computer(String cpu, String ram) {
        this.cpu = cpu;
        this.ram = ram;
    }
    public void setUsbCount(int usbCount) {
        this.usbCount = usbCount;
    }
    public void setKeyboard(String keyboard) {
        this.keyboard = keyboard;
    }
    public void setDisplay(String display) {
        this.display = display;
    }
    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", ram='" + ram + '\'' +
                ", usbCount=" + usbCount +
                ", keyboard='" + keyboard + '\'' +
                ", display='" + display + '\'' +
                '}';
    }
}

第二步:抽象构建者类

public abstract class ComputerBuilder {
    public abstract void setUsbCount();
    public abstract void setKeyboard();
    public abstract void setDisplay();

    public abstract Computer getComputer();
}

第三步:实体构建者类,我们可以根据要构建的产品种类产生多了实体构建者类,这里我们需要构建两种品牌的电脑,苹果电脑和联想电脑,所以我们生成了两个实体构建者类。

苹果电脑构建者类

public class MacComputerBuilder extends ComputerBuilder {
    private Computer computer;
    public MacComputerBuilder(String cpu, String ram) {
        computer = new Computer(cpu, ram);
    }
    @Override
    public void setUsbCount() {
        computer.setUsbCount(2);
    }
    @Override
    public void setKeyboard() {
        computer.setKeyboard("苹果键盘");
    }
    @Override
    public void setDisplay() {
        computer.setDisplay("苹果显示器");
    }
    @Override
    public Computer getComputer() {
        return computer;
    }
}

联想电脑构建者类

public class LenovoComputerBuilder extends ComputerBuilder {
    private Computer computer;
    public LenovoComputerBuilder(String cpu, String ram) {
        computer=new Computer(cpu,ram);
    }
    @Override
    public void setUsbCount() {
        computer.setUsbCount(4);
    }
    @Override
    public void setKeyboard() {
        computer.setKeyboard("联想键盘");
    }
    @Override
    public void setDisplay() {
        computer.setDisplay("联想显示器");
    }
    @Override
    public Computer getComputer() {
        return computer;
    }
}

第四步:指导者类(Director)

public class ComputerDirector {
    public void makeComputer(ComputerBuilder builder){
        builder.setUsbCount();
        builder.setDisplay();
        builder.setKeyboard();
    }
}

使用
首先生成一个director (1),然后生成一个目标builder (2),接着使用director组装builder (3),组装完毕后使用builder创建产品实例 (4)。

public static void main(String[] args) {
        ComputerDirector director=new ComputerDirector();//1
        ComputerBuilder builder=new MacComputerBuilder("I5处理器","三星125");//2
        director.makeComputer(builder);//3
        Computer macComputer=builder.getComputer();//4
        System.out.println("mac computer:"+macComputer.toString());

        ComputerBuilder lenovoBuilder=new LenovoComputerBuilder("I7处理器","海力士222");
        director.makeComputer(lenovoBuilder);
        Computer lenovoComputer=lenovoBuilder.getComputer();
        System.out.println("lenovo computer:"+lenovoComputer.toString());
}

输出结果如下:

mac computer:Computer{cpu='I5处理器', ram='三星125', usbCount=2, keyboard='苹果键盘', display='苹果显示器'}
lenovo computer:Computer{cpu='I7处理器', ram='海力士222', usbCount=4, keyboard='联想键盘', display='联想显示器'}

但是现在都2021年了,基本上lombok这种插件在大部分项目还是能够支持的,所以如非必要,主要还是学习一下建造者模式的思想,别苦哈哈的去实现哈。

–我是“道祖且长”,一个在互联网"苟且偷生"的Java程序员
“有任何问题,可评论,我看到就会回复”

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

三七有脾气

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

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

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

打赏作者

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

抵扣说明:

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

余额充值