设计模式
来源:互联网 发布:凯迪拉克atsl轮毂数据 编辑:程序博客网 时间:2024/06/02 05:17
概述
建造者(builder)模式,也是我们常见的一种模式,有没有想过我们什么时候适合使用建造者模式呢?
从我们周围世界来说,如果我们想“建造”一辆汽车,我们可以手工一点点地去建造,也可以选择将“建造”汽车分为几个部分,比如建造轮子,建造底盘,建造架子,建造发动机等等,然后再组装在一起,从我们的感知上来说,显然分部分建造更符合我们的认知,因为这样很容易形成标准,给人感觉也更清晰。
同时,在软件中,我们构造一个复杂对象也是一样的道理,我们期待能够一步一步地方便我们的创建。这特别适合那种成员特别多,而且部分是required的,部分是optional的对象的构造。
实现
现在比如有一个用户User类,包含网站登陆用户的信息,我们需要的刻画信息有:
public class User { private String uid; // required,用户id private String name; // required,用户名 private String address; // optional,用户地址 private int age; // optional,用户年龄 private String phone; // optional,用户手机号}
上述User类有两个必须的属性,三个可选属性,如果让你构造一个实例,你会怎么构造呢。大部分,我们会选择用构造函数或者setter和getter属性来处理我们元素的值。那如果我们希望类的元素是final的,即不可变的,用什么方式来处理呢。
显而易见,setter和getter方式是我们最常用的,但是如果希望这个被建造的类初始化后不再修改,或者能够控制参数,就可以考虑下建造者模式了,直接实现示例如下:
public class User { private final String uid; // required,用户id private final String name; // required,用户名 private final String address; // optional,用户地址 private final int age; // optional,用户年龄 private final String phone; // optional,用户手机号 // User类只提供getter方法,此处省略 private User(UserBuilder builder) { this.uid = builder.uid; this.name = builder.name; this.address = builder.address; this.phone = builder.phone; this.age = builder.age; } public static class UserBuilder { private final String uid; private final String name; private String address = ""; private int age = -1; private String phone = ""; public UserBuilder(String uid, String name) { this.uid = uid; this.name = name; } public UserBuilder age(int age) { this.age = age; return this; } public UserBuilder address(String address) { this.address = address; return this; } public UserBuilder phone(String phone) { this.phone = phone; return this; } public User build() { return new User(this); } } public static void main(String[] args) { User user = new UserBuilder("111", "jack") .address("china") .age(20) .build(); }}
再举一个例子,比如,有一个接收查询请求的服务,我们构造查询条件,返回响应信息,查询条件是:
public class QueryCondition { private String query_word; // required,查询词 private String ip; // optional,查询来源地址 private String caller; // optional,查询方 private List<String> ret_fields;// optional,查询返回的数据字段}
我们该如何设计一个建造者模式来构造该查询条件呢,示例如下:
public class QueryCondition { private final String query_word; // optional,查询词 private final String ip; // optional,查询来源地址 private final String caller; // optional,查询方 private final List<String> ret_fields;// optional,查询返回的数据字段 public String getQuery_word() { return query_word; } public String getIp() { return ip; } public String getCaller() { return caller; } public List<String> getRet_fields() { return ret_fields; } public QueryCondition(String query_word, String ip, String caller, List<String> ret_fields) { this.caller = caller; this.query_word = query_word; this.ip = ip; this.ret_fields = ret_fields; }}public class QueryConditionBuilder { private String query_word = ""; // required,查询词 private String ip = ""; // optional,查询来源地址 private String caller = "default"; // optional,查询方 private List<String> ret_fields = new ArrayList<String>();// optional,查询返回的数据字段 private QueryConditionBuilder() { } public static QueryConditionBuilder createBuilder() { return new QueryConditionBuilder(); } public QueryConditionBuilder setQueryWord(String query_word) throws Exception { if (query_word == null) { throw new Exception("query word is null"); } this.query_word = query_word; return this; } public QueryConditionBuilder setIp(String ip) { this.ip = ip; return this; } public QueryConditionBuilder setCaller(String caller) { this.caller = caller; return this; } public QueryConditionBuilder setRetFields(List<String> ret_fields) throws Exception { if (ret_fields == null || ret_fields.isEmpty()) { throw new Exception("qeury ret field error"); } this.ret_fields = ret_fields; return this; } public QueryCondition build() { return new QueryCondition(query_word, ip, caller, ret_fields); }}
我们可以看到,通过建造者模式,我们还可以对构造对象的参数进行统一管理和限制,避免未完整初始化的对象被使用。
以上就是建造者模式,其实也很简单,对不对。
【参考资料】建造者模式实践
【参考资料】建造者模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式~~~~~~~~~~
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 2.vue.js实例:双向数据绑定实例
- easyUI中的formatter用法
- 《ACM程序设计》书 训练题中的H题
- 深入剖析Tomcat 第二章 一个简单的Servlet服务器
- 解决intellij idea新建maven项目,加载archetype模型很慢
- 设计模式
- LeetCode之Palindrome Number(回文数)
- MIT的《深度学习》精读(9)
- 对于模态框的使用
- 2017 BAT某家实习生电面---第一次电面的惨痛经历
- webrtc 的回声抵消算法
- 页面滚动时,动态添加css动画
- LeetCode 141. Linked List Cycle(C++版)
- 大小堆实现