Builder模式

2019-10-26  本文已影响0人  四喜汤圆

一、作用

工匠若水-设计模式(创建型)之建造者模式(Builder Pattern)

用于构建复杂的对象,将构建的内部细节隐藏起来。使用者只需按照约定好的规则做相应的配置来完成构建,然后将配置好的对象表示出来即可。

把复杂对象的构建,拆解成几个小部分。当我们面临着一个复杂对象的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

我们参考AlertDialog,对于一个Dialog而言,它的基本构成是复杂的(有标题,内容,按钮及其对应的事件等等属性),但是在实际需求中,不同的界面,我们需要展示给用户的Dialog是不一样的(标题不一样,内容不一样,点击事件也不一样),这些各个部分都是在不断剧烈的变化,但是他们组合起来是相对稳定的(就是一个Dialog弹出展示在界面上)。

在这种情况下,我们可以尝试使用Builder模式,和普通的构造器生成对象不同,如果没有需求,我们可以忽略配置某些属性——对于Dialog,我可以不去定义title,也可以不去定义取消按钮的点击事件,他们内部都有默认的处理;此外,对于API的设计来讲,Builder模式更利于去扩展新的功能或者属性。

与工厂模式相比

建造者模式一般用来创建更为复杂的对象,因为对象的创建过程更为复杂,因此将对象的创建过程独立出来组成一个新的导演类

使用场景:

二、概念

1.角色

三、使用

1.详细的使用

public class ProgramMonkey {
    private boolean isLiteratal;
    private boolean isKnowMath;
    private String language;
    private boolean isKnowDesign;

    public boolean isLiteratal() {
        return isLiteratal;
    }

    public void setLiteratal(boolean literatal) {
        isLiteratal = literatal;
    }

    public boolean isKnowMath() {
        return isKnowMath;
    }

    public void setKnowMath(boolean knowMath) {
        isKnowMath = knowMath;
    }

    public String getLanguage() {
        return language;
    }

    public void setLanguage(String language) {
        this.language = language;
    }

    public boolean isKnowDesign() {
        return isKnowDesign;
    }

    public void setKnowDesign(boolean knowDesign) {
        isKnowDesign = knowDesign;
    }

    @Override
    public String toString() {
        return "ProgramMonkey{" +
                "isLiteratal=" + isLiteratal +
                ", isKnowMath=" + isKnowMath +
                ", language='" + language + '\'' +
                ", isKnowDesign=" + isKnowDesign +
                '}';
    }
}
public abstract class Builder {
    public abstract void buildIsLiteratal(boolean isLiteratal);

    public abstract void buildIsKnowMath(boolean isKnowMath);

    public abstract void buildwLanguage(String language);

    public abstract void buildIsKnowDesign(boolean isKnowDesign);

    public abstract ProgramMonkey getMonkey();
}
public class ConcreteBuilder extends Builder {
    private ProgramMonkey mMonkey = new ProgramMonkey();

    @Override
    public void buildIsLiteratal(boolean isLiteratal) {
        mMonkey.setLiteratal(isLiteratal);
    }

    @Override
    public void buildIsKnowMath(boolean isKnowMath) {
        mMonkey.setKnowMath(isKnowMath);

    }

    @Override
    public void buildwLanguage(String language) {
        mMonkey.setLanguage(language);

    }

    @Override
    public void buildIsKnowDesign(boolean isKnowDesign) {
        mMonkey.setKnowDesign(isKnowDesign);
    }

    @Override
    public ProgramMonkey getMonkey() {
        return mMonkey;
    }
}
public class Director {
    Builder mBuilder = new ConcreteBuilder();

    public ProgramMonkey getLowMonkey() {
        mBuilder.buildIsLiteratal(true);
        mBuilder.buildIsKnowDesign(true);
        mBuilder.buildIsKnowMath(true);
        mBuilder.buildwLanguage("Java");
        return mBuilder.getMonkey();

    }

    public ProgramMonkey getHighMonkey() {
        mBuilder.buildIsLiteratal(true);
        mBuilder.buildIsKnowDesign(true);
        mBuilder.buildIsKnowMath(true);
        mBuilder.buildwLanguage("Android");
        return mBuilder.getMonkey();
    }
}

2.简化的使用

一般将抽象构建者、具体构建者、指挥者三者合为一体。

public class MyProgramMonkey {
    private boolean isLiteratal;
    private boolean isKnowMath;
    private String language;
    private boolean isKnowDesign;

    public static class Builder {
        /**
         * 产品的各个组成部分有默认值,如果构建产品时不特殊指定,则使用默认值
         */
        private boolean isLiteratal = false;
        private boolean isKnowMath = false;
        private String language = "Java";
        private boolean isKnowDesign = false;

        /**
         * 具体部件的构建
         * 
         * @param isLiteratal
         * @return
         */
        public Builder setIsLiterratal(boolean isLiteratal) {
            this.isLiteratal = isLiteratal;
            return this;
        }

        public Builder setIsKnowMath(boolean isKnowMath) {
            this.isKnowMath = isKnowMath;
            return this;
        }

        public Builder setLanguage(String language) {
            this.language = language;
            return this;
        }

        public Builder setIsKnowDesign(boolean isKnowDesign) {
            this.isKnowDesign = isKnowDesign;
            return this;
        }

        /**
         * 按照特定的规则组装各个具体部件
         * 
         * @return
         */
        public MyProgramMonkey create() {
            MyProgramMonkey monkey = new MyProgramMonkey();
            monkey.isLiteratal = isLiteratal;
            monkey.isKnowMath = isKnowMath;
            monkey.language = language;
            monkey.isKnowDesign = isKnowDesign;
            return monkey;
        }
    }
}

3.在ImageLoader中的使用

public class ImageConfig {
    String a = "a";
    String b = "b";
    boolean c=false;

    public static class Builder{
        String a = "a";
        String b = "b";
        boolean c=false;

        /**
         * 具体部件的构建
         * @param a
         * @return
         */
        public Builder setA(String a) {
            this.a = a;
            return this;
        }

        public Builder setB(String b) {
            this.b = b;
            return this;
        }

        public Builder setC(boolean c) {
            this.c = c;
            return this;
        }

        /**
         * 按照特定规则将各个组件组建为产品
         * @return
         */
        public ImageConfig create() {
            ImageConfig imageConfig = new ImageConfig();
            imageConfig.a = a;
            imageConfig.b = b;
            imageConfig.c = c;
            return imageConfig;
        }
    }

}
public class ImageLoader {
    private ImageConfig mImageConfig;

    private ImageLoader() {
        // nothing
    }

    public static ImageLoader getInstance() {
        return SingletonHolder.instance;
    }

    private static class SingletonHolder {
        private static final ImageLoader instance = new ImageLoader();
    }

    public void init(ImageConfig config) {
        this.mImageConfig = config;
    }

    // 其他方法等

}

使用

@Test
public void test3() {
    ImageConfig imageConfig = new ImageConfig.Builder().setA("A").setC(true).create();
    ImageLoader.getInstance().init(imageConfig);
}

参考文献

工匠若水-设计模式(创建型)之建造者模式(Builder Pattern)
SheHuan-Builder(建造者)模式

上一篇下一篇

猜你喜欢

热点阅读