博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java 高效编程之 Builder 模式
阅读量:6577 次
发布时间:2019-06-24

本文共 5218 字,大约阅读时间需要 17 分钟。

前言

在《Effective Java 第2版》中有提到,遇到多个构造器参数时要考虑使用构建器(Builder模式)。相比于重叠构造器(telescoping constructor)模式和JavaBeans模式,Builder模式实现的对象更利于使用。 下面从一个Person例子进行分析以上三种设计模式的使用,Person类有两个必要参数(id和name),有5个可选参数(age,sex,phone,address和desc)

如果你依然在编程的世界里迷茫,不知道自己的未来规划,可以加入JAVA架构学习交流群:835544715 里面可以与大神一起交流并走出迷茫。进群免费领取学习资料,看看前辈们是如何在编程的世界里傲然前行!群里不停更新最新的教程和学习方法(进群送JAVA架构视频资料),有想学习JAVA的,或是转行,还有工作中想提升自己能力的,正在学习的小伙伴欢迎加入学习

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;    }}复制代码

从上面的代码中,当你想要创建实例的时候,就利用参数列表最短的构造器,但该列表中包含了要设置的所有参数:

Person person = new Persion(1, "李四", 20, "男", "18800000000", "China", "测试使用重叠构造器模式");
这个构造器调用通常需要许多你本不想设置的参数,但还是不得不为它们传递值。
一句话:重叠构造器可行,但是当有许多参数的时候,创建使用代码会很难写,并且较难以阅读。

2 JavaBeans模式

遇到许多构造器参数的时候,还有第二种代替办法,即JavaBeans模式。在这种模式下,调用一个无参构造器来创建对象,然后调用setter办法来设置每个必要的参数,以及每个相关的可选参数:

/** * 使用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;    }}复制代码

这种模式弥补了重叠构造器模式的不足。创建实例很容易,这样产生的代码读起来也很容易:

Person person = new Person();
person.setId(1);
person.setName("李四");
person.setAge(20);
person.setSex("男");
person.setPhone("18800000000");
person.setAddress("China");
person.setDesc("测试使用JavaBeans模式");
遗憾的是,JavaBeans模式自身有着很重要的缺点。因为构造过程被分到了几个调用中,在构造过程中JavaBean可能处于不一致的状态。类无法仅仅通过检验构造器参数的有效性来保证一致性。

3 Builder模式(推荐) 幸运的是,还有第三种替代方法,既能保证像重叠构造器模式那样的安全性,也能保证像JavaBeans模式那么好的可读性。这就是Builder模式的一种形式,不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或者静态工厂),得到一个builder对象。然后客户端在builder对象上调用类似于setter的方法,来设置每个相关的可选参数。最后,客户端调用无参的builder方法来生成不可变的对象。这个builder是它构建类的静态成员类。下面就是它的示例:

/** * 使用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;        }        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);        }    }}复制代码

想要学习Java高架构、分布式架构、高可扩展、高性能、高并发、性能优化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分布式项目实战学习架构师视频免费获取 架构群:835544715

点击链接加入群聊【JAVA高级架构】:

注意Person是不可变得,所有的默认参数值都单独放在一个地方。builder的setter方法返回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());    }}复制代码

这样的客户端代码很容易编写,更为重要的是,易于阅读。

转载地址:http://dqwno.baihongyu.com/

你可能感兴趣的文章
锋利的jQuery-2--判断jQuery获取到的对象是否存在$().length
查看>>
20个使用手写字体的创意网站作品欣赏
查看>>
在Pycharm中使用GitHub
查看>>
linux 查询系统版本命令、查询端口号是否被占用命令
查看>>
java笔记八:IO流之字符流与字符缓冲流
查看>>
Docker 命令收集
查看>>
myeclipse注册码生成器
查看>>
BW数据源深入研究
查看>>
【转】接口测试总结
查看>>
怎样快速学好PHP技术之PHP学习方法总结
查看>>
这是歌手,马云
查看>>
泰国商家频繁被问是否支持手机付款,竟向游客放大招!
查看>>
30PB数据1年内迁移到Spark,eBay的经验有何可借鉴之处?
查看>>
你不可不知的GopherChina大咖讲师们
查看>>
余承东再会张近东 战略合作升级点燃818第一把火
查看>>
蚂蚁金服董事长彭蕾开微博 支付宝小编差点惹祸遭劝退
查看>>
拥有华为Mate 9,无需健身房自己练一样有效
查看>>
开启千元快充时代 魅族发布魅蓝5s 售价799元起
查看>>
趣店季报图解:营收环比降14% 大白汽车收入近6亿
查看>>
人民币中间价“四连涨”迫近6.6区间 创逾半年新高
查看>>