设计模式

来源:互联网 发布:凯迪拉克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);    }}

我们可以看到,通过建造者模式,我们还可以对构造对象的参数进行统一管理和限制,避免未完整初始化的对象被使用。
以上就是建造者模式,其实也很简单,对不对。


【参考资料】建造者模式实践
【参考资料】建造者模式

0 0
原创粉丝点击