Java创建对象,设计模式之Builder模式

在《Effective Java》中有提到,遇到多个构造器参数时要考虑使用构建器(Builder模式)。相比于重叠构造器(telescoping constructor)模式和JavaBeans模式,Builder模式实现的对象更利于使用。

1.重叠构造器

普遍使用,不易扩展
构造器的调用通常需要很多你原本不想设置的参数,但你还是不得不给这些参数传一个值进去
总结,是可行,只是当有很多参数时,会让客户端代码很难编写,而且代码也很难阅读,后期不好维护

/**
 * 使用重叠构造器模式
 */
public class Person {   
    //必要参数
    private final int id;
    private final String name;
    //可选参数
    private final int age;
    private final String sex;
    private final String phone;
    private final String address;
    private final String desc;

    public Person(int id, String name) {
        this(id, name, 0);
    }

    public Person(int id, String name, int age) {
        this(id, name, age, "");
    }

    public Person(int id, String name, int age, String sex) {
        this(id, name, age, sex, "");
    }

    public Person(int id, String name, int age, String sex, String phone) {
        this(id, name, age, sex, phone, "");
    }

    public Person(int id, String name, int age, String sex, String phone, String address) {
        this(id, name, age, sex, phone, address, "");
    }

    public Person(int id, String name, int age, String sex, String phone, String address, String desc) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.phone = phone;
        this.address = address;
        this.desc = desc;
    }
}

2.JavaBeans模式

传统方式,容易阅读

/**
 * 使用JavaBeans模式
 */
public class Person {
    //必要参数
    private int id;
    private String name;
    //可选参数
    private int age;
    private String sex;
    private String phone;
    private String address;
    private String desc;

    public void setId(int id) {
        this.id = id;
    }

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

    public void setAge(int age) {
        this.age = age;
    }

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

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}

3.Builder 模式

易于扩展与维护
区分必传参数与可选参数,Builder构造必传参数,剩下的通过链式编程拼接
足够多参数(比如4个,或者更多)的情况下,我们才会去推荐使用它


/**
 * 使用Builder模式
 */
public class Person {
    //必要参数
    private final int id;
    private final String name;
    //可选参数
    private final int age;
    private final String sex;
    private final String phone;
    private final String address;
    private final String desc;

    private Person(Builder builder) {
        this.id = builder.id;
        this.name = builder.name;
        this.age = builder.age;
        this.sex = builder.sex;
        this.phone = builder.phone;
        this.address = builder.address;
        this.desc = builder.desc;
    }

    public static class Builder {
        //必要参数
        private final int id;
        private final String name;
        //可选参数
        private int age;
        private String sex;
        private String phone;
        private String address;
        private String desc;
       
        //必要参数构造器的构造方法
        public Builder(int id, String name) {
            this.id = id;
            this.name = name;
        }
        //可选参数实现链式编程,返回Builder对象
        public Builder age(int val) {
            this.age = val;
            return this;
        }

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

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

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

        public Builder desc(String val) {
            this.desc = val;
            return this;
        }
        //构造返回目标对象
        public Person build() {
            return new Person(this);
        }
    }
}

Builder模式使用代码

/**
 * 测试使用
 */
public class Test {

    public static void main(String[] args) {
        Person person = new Person.Builder(1, "张三")
                .age(18).sex("男").desc("测试使用builder模式").build();
        System.out.println(person.toString());
    }
}

4.引入lombok的@Builder注解,帮我们简化建造者模式的实现

/**
 * 使用lombok的注解实现build模式
 * @Builder默认只能支持实现全参构造方法的builder模式,并且再也无法通过无参构造方法去创建对象
 * 我们通过添加@AllArgsConstructor和@NoArgsConstructor,实现支持无参构造创建对象,也支持通过     
 * builder模式去构建对象
 */
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class Person {
    //必要参数,使用lombok的注解帮我们检查不允许为空
    @NonNull
    private final int id;
    @NonNull
    private final String name;
    //可选参数
    private final int age;
    private final String sex;
    private final String phone;
    private final String address;
    private final String desc;
}

Builder模式使用代码

/**
 * 测试使用
 */
public class Test {

    public static void main(String[] args) {
        Person person = new Person.Builder.id(1).name("张三")
                .age(18).sex("男").desc("测试使用builder模式").build();
        System.out.println(person.toString());
    }
}

你可能感兴趣的:(java,设计模式)