设计模式-Builder设计模式

作者: 请叫我张懂 | 来源:发表于2018-02-26 14:43 被阅读54次

    Builder(建造者)设计模式的定义

    将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

    使用套路

    • 静态内部类使用链式调用的方式来设置类的表现形式
    • 私有外部类的构造方法,通过静态内部来获取参数进行表现

    强调

    • 链式调用并不是Builder设计模式,只是一种手法,来提高编码速度和代码可读性,如:RxJava 将链式编程用到的极致。想必有一些人会把 链式调用Builder设计模式 混为一谈。

      Flowable.just("Hello world")
        .subscribe(new Consumer<String>() {
         @Override public void accept(String s) {
          System.out.println(s);
            }
        });
      

    类图

    Buidler设计模式类图.png
    • Director: 统一组装的过程
    • Builder: 抽象的Builder类
    • ConcreateBuilder: 具体的Builder类
    • Product: 产品的抽象类

    上面描述的是经典的Builder设计模式的类图,但是我们在实际使用过程中为了避免产生多余的对象,消耗多余的内存,Direcotr 通常是被省略掉。而是通过 Builder 来进行组装,并且通过链式调用来设置参数。

    示例代码

    示例1

    public class Human {
        private final String mNo;
        private final String mName;
        private final int mAge;
    
        private Human(Builder builder) {
            this.mNo = builder.no;
            this.mName = builder.name;
            this.mAge = builder.age;
        }
    
        public int getAge() {
            return mAge;
        }
    
        public String getName() {
            return mName;
        }
    
        public String getNo() {
            return mNo;
        }
    
        public static class Builder {
            private final String no;
            private String name;
            private int age;
    
            public Builder(String no) {
                this.no = no;
            }
    
            public Builder setName(String name) {
                this.name = name;
                return this;
            }
    
            public Builder setAge(int age) {
                this.age = age;
                return this;
            }
    
            public Human build() {
                return new Human(this);
            }
        }
    }
    
    调用
        Human human = new Human.Builder("123456")
                .setName("lisi")
                .setAge(20)
                .build();
    

    上面一段代码是一个基本的 Builder设计模式的代码。通过实例化 Human 中的 Builder 对象来设置属性,最后我们在调用 build() 方法实例化 Human 对象。而且我们可以在 build() 中进行一些判空和数据初始化。

    public Human build() {
            if (TextUtils.isEmpty(name)) {
                name = "未知";
            }
            return new Human(this);
    }
    

    示例2

    之前在Logger源码分析理解时,它的 PrettyFormatStrategyCsvFormatStrategy 均使用了 Builder设计模式,但是与 示例1 稍有些不同。

    public class Human {
        private final String mNo;
        private final String mName;
        private final int mAge;
    
        private Human(Builder builder) {
            this.mNo = builder.no;
            this.mName = builder.name;
            this.mAge = builder.age;
        }
    
        public static Builder newBuilder(String no) {
            return new Builder(no);
        }
    
        public int getAge() {
            return mAge;
        }
    
        public String getName() {
            return mName;
        }
    
        public String getNo() {
            return mNo;
        }
    
        public static class Builder {
            private final String no;
            private String name;
            private int age;
    
            private Builder(String no) {
                this.no = no;
            }
    
            public Builder setName(String name) {
                this.name = name;
                return this;
            }
    
            public Builder setAge(int age) {
                this.age = age;
                return this;
            }
    
            public Human build() {
                if (TextUtils.isEmpty(name)) {
                    name = "未知";
                }
                return new Human(this);
            }
        }
    }
    
    调用
    Human human = Human.newBuilder("123456")
                .setName("lisi")
                .setAge(20)
                .build();
    

    总结

    • Builder 在很多系统框架以及第三框架中都有使用,如:AlertDialog,OkHttp等,可以通过理解它们的源码进行更深的学习
    • 如果类中有很多参数,并且有很多参数都是有默认值的时候就可以使用 Buidler设计模式

    相关文章

      网友评论

        本文标题:设计模式-Builder设计模式

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