美文网首页
Java设计模式之建造者模式(原型/链式)

Java设计模式之建造者模式(原型/链式)

作者: 意识流丶 | 来源:发表于2018-11-29 23:11 被阅读17次

    什么是建造者模式?

    建造者模式是一种创建型模式,
    建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创造不同的表示。建造对象的时候只需要指定需要建造的类型,而不必了解具体的建造过程。
    主要特点是通过逐步添加单体对象形成一个复杂的对象。

    可以参考https://blog.csdn.net/u010102390/article/details/80179754
    解释得非常好

    建造者模式中有原型写法和链式写法

    原型写法

    经典Buider模式分为四块:
    Product:被构造的复杂对象
    Builder:抽象接口
    BuilderImpl:抽象接口的具体实现
    Director:接口的构造者和使用者

    经典图示
    1529568-a561f9d9dd6bb2c1.png

    实体User类(Product)

    public class User {
        String id;
        String name;
        String password;
        String phone;
      //set/get方法
        @Override
        public String toString() {
            return "User{" +
                    "id='" + id + '\'' +
                    ", name='" + name + '\'' +
                    ", password='" + password + '\'' +
                    ", phone='" + phone + '\'' +
                    '}';
        }
    }
    

    抽象建造者/建造者接口(Builder)

    public interface Build {
        void makeId(String val);
        void makeName(String val);
        void makePassword(String val);
        void makePhone(String val);
        User makeUser();
    }
    

    具体建造者(BuilderImpl)

    public class AdminBuilder implements Build{
        User user=new User();
        @Override
        public User makeUser(){
            return user;
        }
        @Override
        public void makeId(String val) {
            user.setId(val);
        }
        @Override
        public void makeName(String val) {
            user.setName(val);
        }
        @Override
        public void makePassword(String val) {
            user.setPassword(val);
        }
        @Override
        public void makePhone(String val) {
            user.setPhone(val);
        }
    }
    

    Admin指导建造者创建User(Director)

    public class Admin {
        private AdminBuilder adminBuilder;
    
        public void setAdminBuilder(AdminBuilder adminBuilder) {
            this.adminBuilder = adminBuilder;
        }
        public User makeUser(String id,String name,String password,String phone){
            adminBuilder.makeId(id);
            adminBuilder.makeName(name);
            adminBuilder.makePassword(password);
            adminBuilder.makePhone(phone);
            return this.adminBuilder.makeUser();
        }
    }
    

    具体main类

    public static void main(String[] args){
            AdminBuilder adminBuilder=new AdminBuilder();
            Admin admin=new Admin();
            admin.setAdminBuilder(adminBuilder);
            User user=admin.makeUser("1","张三","123456","88888888");
            System.out.println(user.toString());
        }
    

    AdminBuilder adminBuilder=new AdminBuilder(); new具体建造者
    Admin admin=new Admin(); newAdmin指导建造者
    admin.setAdminBuilder(adminBuilder);准备开始建造(不写会报空指针)
    User user=admin.makeUser()根据Admin的建造方法创建User

    运行输出
    image.png

    UML类图

    Package v3.png

    链式写法(非常推荐)

    链式写法是在原型写法的基础上做优化,有些时候Builder的创建部分有默认值,或者不需要的情况下,而产生不同的Product,通过以上方式,就需要修改Director类和Builder类,再或者根据不同的创建顺序,生成不同的结果,也需要修改Director类。Director似乎显得很不稳定和多余。可以通过Builder自身的调用逻辑来生成Product,即链式调用

    使用IDEA的插件生成代码

    首先先在IDEA中安装InnerBuilder插件,可以在实体类中自动生成建造者模式的链式写法
    InnerBuilder插件的官方介绍:http://plugins.jetbrains.com/plugin/7354-innerbuilder
    用法:安装好插件后在实体类中按下alt+insert,然后选择Builder

    实体User类

    public class User {
        String id;
        String name;
        String password;
        String phone;
    
        private User(Builder builder) {
            id = builder.id;
            name = builder.name;
            password = builder.password;
            phone = builder.phone;
        }
    
        public String getId() {
            return id;
        }
    
        public String getName() {
            return name;
        }
    
        public String getPassword() {
            return password;
        }
    
        public String getPhone() {
            return phone;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "id='" + id + '\'' +
                    ", name='" + name + '\'' +
                    ", password='" + password + '\'' +
                    ", phone='" + phone + '\'' +
                    '}';
        }
    
        public static final class Builder {
            private String id;
            private String name;
            private String password;
            private String phone;
    
            public Builder() {
            }
    
            public Builder id(String val) {
                id = val;
                return this;
            }
    
            public Builder name(String val) {
                name = val;
                return this;
            }
    
            public Builder password(String val) {
                password = val;
                return this;
            }
    
            public Builder phone(String val) {
                phone = val;
                return this;
            }
    
            public User build() {
                return new User(this);
            }
        }
    }
    

    重点(相比于普通JavaBean的好处):

    在建造者模式中,提供一个辅助的静态建造器Builder(静态内部类),可以在里面set实体类的属性,与JavaBean不同的是,建造者是先set,在通过build实例化实体类,这样既可以提高代码的阅读性,也可以防止对象没有实例化,就被调用;不会造成不一致性,同时解决了Javabean模式的线程安全问题

    具体main类

    public static void main(String[] args){
            User user=new User.Builder().id("1").name("张三").password("123456")
                                         .phone("15820638007").build();
            System.out.println(user.toString());
        }
    
    运行输出
    image.png

    UML类图

    Package v3.png

    总结:

    Director角色并非多余,能把复杂的Product创建过程对外隐藏,使Builder部件和创建过程分离,各方易于扩展,降低了耦合度。当需要对一个对象设置很多属性,此时就能方便的使用链式调用来提高编码速度和代码可读性。

    相关文章

      网友评论

          本文标题:Java设计模式之建造者模式(原型/链式)

          本文链接:https://www.haomeiwen.com/subject/htlqcqtx.html