常用设计模式学习-构造者模式

构造者模式

我将通过一个简单的Demo来演示构造者模式,在此之前,我假设您已经:

  • 熟悉Java基础
  • 熟悉Java的三大特性

现有一个User类,有如下属性,不使用构造者模式

private String name;
private int age;
private String email;
private String address;

我们为其创建一些构造器,以满足构造出不同属性对象的要求。

	// 无参构造
	public User() {
    
	}
	//1
    public User(String name) {
        this.name = name;
    }
    //2
    public User(int age) {
        this.age = age;
    }
    //3
    public User(String name, String email) {
        this.name = name;
        this.email = email;
    }
    //4
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //5
    public User(int age, String name) {
        this.age = age;
        this.name = name;
    }

可以看到,上面的几个构造器构成了重载。

重载有三种形式:

  • 参数类型不同,比如方法1,方法2
  • 参数个数不同,比如方法1,方法3
  • 参数顺序不同,比如方法4,方法5

❓那下面两个构造器大家观察下,还能和上面构造器构成重载吗

	//6
    public User(String email, String name) {
        this.email = email;
        this.name = name;
    }

	//7
    public User(int age, String address) {
        this.age = age;
        this.address = address;
    }

比如方法3,方法6构成重载吗?方法5,方法7能构成重载吗?

答案都是否定的。不能构成重载。

分析:

  • 方法6对于方法3来说,参数类型一样,参数个数一样,不能构成重载。
  • 方法7对于方法5来说,参数类型一样,参数个数一样,不能构成重载。

那如果我真的就需要构造两个User对象:

  • 一个有age和name属性
  • 一个有age和address属性

怎么办?此时,java构造器的编写就出现了问题了。

那如果才能无拘无束地优雅地构造自己想要的对象?属性值想怎么传怎么传,想先传哪个就传哪个,都能把对象给构造好。

答案就是构造者模式,能够帮我们解决这个痛点,让我们的代码更加优雅。


现有一个Employee类,有如下属性,

	private String name;
    private int age;
    private String email;
    private String address;

构造者模式有几个特点

  • 需要构造的目标对象Employee,无参构造器应该为private
  • Employee需要一个静态内部类Builder
  • Builder拥有与Employee相同的属性
  • Builder需要一个public修饰的无参构造器
  • Builder需要为属性生成set方法,返回类型为Builder类型,set方法需要返回this
  • Builder需要一个public修饰的build方法,用来创建Employee对象,所以返回类型为Employee

以下为代码实现:

public class Employee {
    private String name;
    private int age;
    private String email;
    private String address;
    /**
     * 无参构造器私有,禁止外界通过该方式实例化对象
     */
    private Employee() {
    }
    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", email='" + email + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
    /**
     * 静态内部类Builder
     */
    public static class Builder {
        // 与Employee拥有相同的属性
        private String name;
        private int age;
        private String email;
        private String address;

        public Builder() {
        }

        // set方法
        // 1,需要有返回值,返回类型为Builder对象;
        // 2,需要return this; 这样才能链式调用
        public Builder setName(String name) {
            this.name = name;
            return this;
        }

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

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

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

        /**
         * 通过build方法来创建Employee对象
         * public 外界可以调用
         * @return Employee对象
         */
        public Employee build() {
            Employee employee = new Employee();
            employee.name = this.name;
            employee.age = this.age;
            employee.email = this.email;
            employee.address = this.address;
            return employee;
        }

    }

}

接下来,我们看测试类

public class BuilderTest {
    public static void main(String[] args) {
        System.out.println("在这里插入代码片======================不用构造者模式===========================");
        // 测试构造User对象
        User user1 = new User();
        User user2 = new User("诸葛亮");
        User user3 = new User(27);
        User user4 = new User("张飞", "1111@qq.com");
        User user5 = new User("1112@qq.com", "关羽");

        System.out.println(user1.toString());
        System.out.println(user2.toString());
        System.out.println(user3.toString());
        System.out.println(user4.toString());
        System.out.println(user5.toString());

        System.out.println("=====================用构造者模式============================");

        Employee employee1 = new Employee.Builder().build();
        Employee employee2 = new Employee.Builder().setName("诸葛亮").build();
        Employee employee3 = new Employee.Builder().setAge(27).build();
        Employee employee4 = new Employee.Builder().setName("张飞").setEmail("1111@qq.com").build();
        Employee employee5 = new Employee.Builder().setEmail("1112@qq.com").setName("关羽").build();

        System.out.println(employee1.toString());
        System.out.println(employee2.toString());
        System.out.println(employee3.toString());
        System.out.println(employee4.toString());
        System.out.println(employee5.toString());

    }

输出结果如下:

======================不用构造者模式===========================
User{name='null', age=0, email='null', address='null'}
User{name='诸葛亮', age=0, email='null', address='null'}
User{name='null', age=27, email='null', address='null'}
User{name='张飞', age=0, email='1111@qq.com', address='null'}
User{name='1112@qq.com', age=0, email='关羽', address='null'}
=====================用构造者模式============================
Employee{name='null', age=0, email='null', address='null'}
Employee{name='诸葛亮', age=0, email='null', address='null'}
Employee{name='null', age=27, email='null', address='null'}
Employee{name='张飞', age=0, email='1111@qq.com', address='null'}
Employee{name='关羽', age=0, email='1112@qq.com', address='null'}

从结果第5,6行和11,12行对比可以看出:构造者模式可以帮我们更加方便快捷自由地创建我们需要的对象。

结束语

ok各位,以上就是这篇文章的全部内容了,非常感谢你能看到这里。如果你觉得这篇文章对你有所帮助求赞求收藏求评论求转发,别忘了点一个大大的关注,各位的支持就是我最大的动力,再见!邮箱:734140820@qq.com

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wpw5499

若有帮助,不妨请博主一杯奶茶吧

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

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

打赏作者

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

抵扣说明:

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

余额充值