设计模式-建造者模式

定义

定义:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。

模式的角色和类图

角色

建造者(Builder)模式的主要角色如下。

  • 产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
  • 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
  • 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
  • 具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
  • 指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。

类图

在这里插入图片描述

实现

具体代码如下:

/**
 * @author hao
 *  产品类
 */
public class Phone {
    protected String cpu;
    protected String camara;
    protected String screen;
    protected String battery;

    @Override
    public String toString() {
        return "Phone{" +
                "cpu='" + cpu + '\'' +
                ", camara='" + camara + '\'' +
                ", screen='" + screen + '\'' +
                ", battery='" + battery + '\'' +
                '}';
    }
}
/**
 * 抽象建造者
 */
public interface PhoneBuilder {
    Phone phone = new Phone();

    void AssemblyCpu(String cpu);
    void AssemblyCamara(String camara);
    void AssemblyScreen(String screen);
    void AssemblyBattery(String battery);

    Phone build();
}
/**
 * 具体建造者
 */
public class HwPhoneBuilder implements PhoneBuilder{


    @Override
    public void AssemblyCpu(String cpu) {
        phone.cpu = cpu;
    }

    @Override
    public void AssemblyCamara(String camara) {
        phone.camara = camara;
    }

    @Override
    public void AssemblyScreen(String screen) {
        phone.screen = screen;
    }

    @Override
    public void AssemblyBattery(String battery) {
        phone.battery = battery;
    }

    @Override
    public Phone build() {
        return this.phone;
    }
}
/**
 * 指挥者类
 */
public class Direct {
    private PhoneBuilder builder;

    public Direct(PhoneBuilder builder) {
        this.builder = builder;
    }

    public Phone getProduct(String cpu, String camara, String screen, String battery){
        builder.AssemblyCpu(cpu);
        builder.AssemblyCamara(camara);
        builder.AssemblyScreen(screen);
        builder.AssemblyBattery(battery);
        return builder.build();
    }
}

测试代码如下:

public class Maintest {
    public static void main(String[] args){
        Direct direct = new Direct(new HwPhoneBuilder());
        Phone huaweiPhone = direct.getProduct("麒麟心", "5000万像素", "高清屏", "7000mA电池");
        System.out.println(huaweiPhone);
    }
}

结果:

Phone{cpu=‘麒麟心’, camara=‘5000万像素’, screen=‘高清屏’, battery=‘7000mA电池’}

这样看起来感觉很复杂。其实我们可以将指挥类和建造者类进行合并,并且实现链式调用。这样可以增强代码的可读性,以及方便我们使用建造者模式。我们去掉指挥类,改造下抽象建造者和具体建造者类,代码如下:

/**
 * @author hao
 * 抽象建造者
 */
public interface PhoneBuilder {
    Phone phone = new Phone();

    PhoneBuilder AssemblyCpu(String cpu);
    PhoneBuilder AssemblyCamara(String camara);
    PhoneBuilder AssemblyScreen(String screen);
    PhoneBuilder AssemblyBattery(String battery);

    Phone build();
}
/**
 * @author hao
 * 具体建造者
 */
public class HwPhoneBuilder implements PhoneBuilder{


    @Override
    public PhoneBuilder AssemblyCpu(String cpu) {
        phone.cpu = cpu;
        return this;
    }

    @Override
    public PhoneBuilder AssemblyCamara(String camara) {
        phone.camara = camara;
        return this;
    }

    @Override
    public PhoneBuilder AssemblyScreen(String screen) {
        phone.screen = screen;
        return this;
    }

    @Override
    public PhoneBuilder AssemblyBattery(String battery) {
        phone.battery = battery;
        return this;
    }

    @Override
    public Phone build() {
        return this.phone;
    }
}

我们再来测试下调用,测试类代码如下:

public class Maintest {
    public static void main(String[] args){
        HwPhoneBuilder builder = new HwPhoneBuilder();
        Phone phone = builder.AssemblyCpu("麒麟心")
                .AssemblyCamara("5000万像素")
                .AssemblyScreen("高清屏")
                .AssemblyBattery("7000mA电池")
                .build();
        System.out.println(phone);

    }
}

结果:

Phone{cpu=‘麒麟心’, camara=‘5000万像素’, screen=‘高清屏’, battery=‘7000mA电池’}

我们实现了链式调用,也简化了代码。
但是仔细看测试类代码。我们发现和lombok中的@Builder标注的类创建对象的代码类似。没错!!

Lombok中的@Builder注解

lombok中的@Builder注解就是建造者模式的实现。
我们给Phone类标注@Builder
然后通过测试类代码进行测试,具体代码如下:

@Builder
public class Phone {
    protected String cpu;
    protected String camara;
    protected String screen;
    protected String battery;

    @Override
    public String toString() {
        return "Phone{" +
                "cpu='" + cpu + '\'' +
                ", camara='" + camara + '\'' +
                ", screen='" + screen + '\'' +
                ", battery='" + battery + '\'' +
                '}';
    }
}

只要一个产品类加上@Builder注解,就可以实现建造者模式。
我们通过代码测试下,测试类代码如下:

public class Maintest {
    public static void main(String[] args){
        Phone phone = Phone.builder()
                .cpu("麒麟心")
                .camara("5000万像素")
                .screen("高清屏")
                .battery("7000mA电池")
                .build();
        System.out.println(phone);
    }
}

测试结果:

Phone{cpu=‘麒麟心’, camara=‘5000万像素’, screen=‘高清屏’, battery=‘7000mA电池’}

得到了同样的结果。@Builder注解首先通过Phone对象得到建造者对象PhoneBuilder然后对属性进行构造。然后调用PhoneBuilder的Build()方法返回构建好的Phone对象,大概就是这么个过程。所以后续我们可以直接利用@Builder注解来使用建造者模式。

至此创建型模式已经讲完````

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值