设计模式之构建者模式

场景

大家有没有碰到过类对象非常的复杂,有些参数是必须有的,但是有些参数又是可选的.例如下面这个类:有很多很多的成员变量,如何构造这个类?

public class Sekiro{
  // 姓名(必须)
  private String name;
  // 年龄(必须)
  private String sex;
  // 武器(必须)
  private String weapon;
  // 手里剑(可选)
  private String swordInHand;
  // 机关斧(可选)
  private String mechanizedAxe;
  // 吹火筒(可选)
  private String blowpipe;
  ...

折叠构造函数模式

先来看第一种方式:折叠构造函数模式

public Sekiro(String name, String sex, String weapon) {
        this.name = name;
        this.sex = sex;
        this.weapon = weapon;
    }

    public Hero(String name, String sex, String weapon, String swordInHand) {
        this.name = name;
        this.sex = sex;
        this.weapon = weapon;
        this.swordInHand = swordInHand;
    }

    public Hero(String name, String sex, String weapon, String mechanizedAxe,String blowpipe) {
        this.name = name;
        this.sex = sex;
        this.mechanizedAxe = mechanizedAxe;
        this.blowpipe = blowpipe;
    }
...

代码阅读以及使用不方便,每次使用需要知道调用哪种构造方法,当参数很多时还需要注意参数顺序,易出错。

JavaBean模式

第二种方式:JavaBean模式,创建一个对象,对其中的成员属性依次set(),get()

 public Sekiro() {
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
     public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

   ...

在构建的过程中对象的状态容易发生变化,造成错误。

构建者模式

针对以上问题,所以才有了Builder模式。当一个类对象非常复杂,构造的参数很多,并且这些参数是可选的,可以考虑使用构建者。
在这里插入图片描述

  • Builder
    构建者接口,定义创建一个Product对象所需的各个部件的操作
  • ConcreteBuilder
    具体的构建器实现,实现各个部件的创建,并负责组装Product对象的各个部件,同时还提供一个让用户获取组装完成后的产品对象的方法
  • Director
    指导者,主要用来使用Builder接口,以一个统一的过程来构建所需要的Product对象。
  • Product
    产品,表示被构建器构建的复杂对象。

针对上述问题使用构建者模式:
1.创建类Sekiro,包含所有成员变量字段(只实现所有成员的get方法)(final修饰必有的成员)
2.创建Sekiro的内部类Builder,拥有Sekiro所有成员变量
3.Builder实现所有的变量的set方法
4.私有化Sekiro构造方法,只能从Builder中赋值获取
5.提供一个返回Sekiro的方法

// 1.创建类Sekiro,包含所有成员变量字段(只实现所有成员的get方法)
public class Sekiro {
    // 姓名(必须)
    private  String name;
    // 年龄(必须)
    private  String sex;
    // 武器(必须)
    private  String weapon;
    // 手里剑(可选)
    private String swordInHand;
    // 机关斧(可选)
    private String mechanizedAxe;
    // 吹火筒(可选)
    private String blowpipe;

   
    // 4.私有化Sekiro构造方法,外部只能通过Builder获取
    private Sekiro(Builder builder) {
        this.name = builder.name;
        this.sex = builder.sex;
        this.weapon = builder.weapon;
        this.swordInHand = builder.swordInHand;
        this.mechanizedAxe = builder.mechanizedAxe;
        this.blowpipe = builder.blowpipe;
    }

    @Override
    public String toString() {
        return "Sekiro{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", weapon='" + weapon + '\'' +
                ", swordInHand='" + swordInHand + '\'' +
                ", mechanizedAxe='" + mechanizedAxe + '\'' +
                ", blowpipe='" + blowpipe + '\'' +
                '}';
    }

 	// 2.创建Sekiro的内部类Builder,拥有Sekiro所有成员变量(final修饰必有的成员)
    static class Builder {
        // 姓名(必须)
        private final String name;
        // 年龄(必须)
        private final String sex;
        // 武器(必须)
        private final String weapon;
        // 手里剑(可选)
        private String swordInHand;
        // 机关斧(可选)
        private String mechanizedAxe;
        // 吹火筒(可选)
        private String blowpipe;

   
         // final修饰的参数为必传
        public Builder(String name, String sex,String weapon) {
            this.name = name;
            this.sex = sex;
            this.weapon = weapon;
        }

   
         // 3.Builder类设置成员参数,实现所有的变量的set方法
         // 返回builder对象,链式编程
        public Builder setSwordInHand(String swordInHand) {
            this.swordInHand = swordInHand;
            return this;
        }

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

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

        // 5.提供一个返回Sekiro的方法
        public Sekiro builder() {
            return new Sekiro(this);
        }

    }
}
// 测试
 public static void main(String[] args) {
        Sekiro sekiro1 = new Sekiro.Builder("只狼", "男", "楔丸")
                .setMechanizedAxe("机关斧")
                .builder();

        Sekiro sekiro2 = new Sekiro.Builder("只狼2", "男", "不死斩拜泪")
                .setMechanizedAxe("机关斧")
                .setSwordInHand("手里剑")
                .builder();

        Sekiro sekiro3 = new Sekiro.Builder("只狼3", "男", "不死斩开门")
                .setMechanizedAxe("机关斧")
                .setMechanizedAxe("手里剑")
                .setSwordInHand("吹火筒")
                .builder();

        System.out.println("第一只狼:"+sekiro1);
        System.out.println("第二只狼:"+sekiro2);
        System.out.println("第三只狼:"+sekiro3);

    }

// 输出
第一只狼:Sekiro{name='只狼', sex='男', weapon='楔丸', swordInHand='null', mechanizedAxe='机关斧', blowpipe='null'}
第二只狼:Sekiro{name='只狼2', sex='男', weapon='不死斩拜泪', swordInHand='手里剑', mechanizedAxe='机关斧', blowpipe='null'}
第三只狼:Sekiro{name='只狼3', sex='男', weapon='不死斩开门', swordInHand='吹火筒', mechanizedAxe='手里剑', blowpipe='null'}

总结

构建者模式是一种强大且灵活的设计模式,可用于构建复杂对象。通过使用构建者模式,我们可以避免在构造函数中传入大量参数,并且能够创建不同表示的对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值