Android设计模式之建造者模式(Builder Pattern)

来源:互联网 发布:dnf本地安全策略优化 编辑:程序博客网 时间:2024/05/01 23:14

一 Builder模式介绍及使用场景

Builder模式是一步一步创建一个复杂对象的创建者模式,它允许用户在不知道内部构建细节的情况下,可以更精细地控制对象的构造流程。该模式是为了将复杂对象的过程和它的部件解耦,使得构建过程和部件的表示隔离开来。

因为一个复杂的对象有很多大量组成部分,如汽车,有车轮、方向盘、发动机,还有各种小零件,如何将这件部件装配成一辆汽车,这个装配过程很漫长,也很复杂,对于这种情况,为了在构建过程中对外部隐藏实现细节,也可以使用Builder模式将部件和组装过程分离,使得构建过程和部件都可以自有拓展,两者之间的耦合也降到最低。

在项目中最常见到的两个使用Builder模式的案例,一个是AlertDialog.Builder的创建,另一个就是著名的图片加载框架ImageLoader的初始配置。

ImageLoader的初始配置如下:

ImageLoaderConfiguration config = new ImageLoaderConfiguration      .Builder(context)      .memoryCacheExtraOptions(480, 800) // max width, max height,即保存的每个缓存文件的最大长宽      .discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75, null) // Can slow ImageLoader, use it carefully (Better don't use it)/设置缓存的详细信息,最好不要设置这个      .threadPoolSize(3)//线程池内加载的数量      .threadPriority(Thread.NORM_PRIORITY - 2)      .memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024)) // You can pass your own memory cache implementation/你可以通过自己的内存缓存实现      .memoryCacheSize(2 * 1024 * 1024)   //设置内存缓存的大小     .discCacheSize(50 * 1024 * 1024)    //设置磁盘缓存的大小    .discCacheFileNameGenerator(new Md5FileNameGenerator())//将保存的时候的URI名称用MD5 加密       .discCacheFileCount(100) //缓存的文件数量      .discCache(new UnlimitedDiscCache(cacheDir))//自定义缓存路径               .defaultDisplayImageOptions(DisplayImageOptions.createSimple())      .imageDownloader(new BaseImageDownloader(context, 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超时时间      .writeDebugLogs() // Remove for release app      .build();//开始构建 //然后    ImageLoader.getInstance().init(config);//全局初始化此配置  

Builder模式的使用场景:
(1)多个部件或零件,不同的执行顺序,产生不同的事件结果时;
(2)多个部件或者零件,都可以装配到一个对象中,但是产生的运行结果又不相同时。
(3)当初始化一个对象特别复杂,参数多,且很多参数都具有默认值。

二 Builder模式的结构图

结构图如下:
角色介绍:
(1)Product:产品的抽象类
(2)Builder:抽象的Builder类,规范产品的组件,一般由子类实现具体的组建过程。
(3)ConcreteBuilder: 具体的Builder类。
(4)Director:统一的组装过程。

这里写图片描述

三 Builder模式的简单DEMO:

不知道大家有没有自己组装过电脑,组装之前我们都得先购买好电脑的各个部件,比如主板,显示器,内存条等,然后安装相应的操作系统。以电脑Computer的三个部件(主板Board,显示器Display,操作系统OS)表示为例:

//计算机抽象类 即是Product角色public abstract class Computer {    //含有主板Board,显示器Display,操作系统OS    protected String mBoard;    protected String mDisplay;    protected String mOs;    protected Computer(){};    //设置主板    public void setmBoard(String mBoard) {        this.mBoard = mBoard;    }    //设置显示器    public void setmDisplay(String mDisplay) {        this.mDisplay = mDisplay;    }    //设置操作系统    public abstract void setmOs();    @Override    public String toString() {        return "Computer{" +                "mBoard='" + mBoard + '\'' +                ", mDisplay='" + mDisplay + '\'' +                ", mOs='" + mOs + '\'' +                '}';    }}

然后比如我们要装一个MAC的电脑:

//具体的Computer类public class Macbook extends  Computer{    public Macbook(){};    @Override    public void setmOs() {        mOs="MAC OS X 10.10";    }}

对应的抽象Builder是:

//抽象的Builder类 规范电脑的组装设置public abstract class Builder {    //设置主机    public abstract void setBoard(String board);    //设置显示器    public abstract void setDisplay(String display);    //设置操作系统    public abstract void setOS();    //创建computer    public abstract Computer create();}

具体的Builder,实现电脑的组装:

//具体的Builder类public class MacbookBuilder extends Builder{    private Computer macComputer=new Macbook();    @Override    public void setBoard(String board) {        macComputer.setmBoard(board);//设置主板    }    @Override    public void setDisplay(String display) {        macComputer.setmDisplay(display);//设置显示器    }    @Override    public void setOS() {        macComputer.setmOs();//设置操作系统    }    @Override    public Computer create() {//创建方法        return macComputer;    }}

客户端实现如下:

  Builder macbookBuilder= new MacbookBuilder();        macbookBuilder.setBoard("英特尔主板");        macbookBuilder.setDisplay("三星显示器");        macbookBuilder.setOS();        String tag1=macbookBuilder.create().toString();        Log.i("TAG",tag1);

打印结果如下:

04-16 06:48:45.899 9551-9551/com.troy.builderpattern I/TAG: Computer{mBoard='英特尔主板', mDisplay='三星显示器', mOs='MAC OS X 10.10'}

上述示例中,通过具体的MacbookBuilder来构建了Macbook对象,并且我们忽略了Director的角色,而直接使用一个Builder来进行对象的组装。

以上的写法中,我们当然我们还可以改写Builder的代码,实现Builder的链式调用,类似ImageLoade初始配置那样,一行代码搞定:

new XBuilder().setA("A").setB("B").setC("C").create( );

改写Builder:

//抽象的Builder public abstract class BuilderWithReturn {    //设置主机    public abstract BuilderWithReturn setBoard(String board);    //设置显示器    public abstract BuilderWithReturn setDisplay(String display);    //设置操作系统    public abstract BuilderWithReturn setOS();    //创建computer    public abstract Computer create();}

改写MacbookBuilder:

//具体的Builder类public class MacbookBuilderWithReturn extends BuilderWithReturn{    private Computer macComputer=new Macbook();    @Override    public BuilderWithReturn setBoard(String board) {        macComputer.setmBoard(board);//设置主板        return this;    }    @Override    public BuilderWithReturn setDisplay(String display) {        macComputer.setmDisplay(display);//设置显示器        return this;    }    @Override    public BuilderWithReturn setOS() {        macComputer.setmOs();//设置操作系统        return this;    }    @Override    public Computer create() {        return macComputer;    }}

客户端实现代码如下:

 BuilderWithReturn macbookBuilderWithReturn=new MacbookBuilderWithReturn();        String tag2=macbookBuilderWithReturn.setBoard("IGT主板").setDisplay("AOC显示器").setOS().create().toString();        Log.i("TAG",tag2);

打印结果:

04-16 06:48:45.899 9551-9551/com.troy.builderpattern I/TAG: Computer{mBoard='IGT主板', mDisplay='AOC显示器', mOs='MAC OS X 10.10'}

这种形式不仅没有Director的角色,整个Builder的链式调用也使得结构变得更加简单了。

总结:Builder模式在Android开发中较为常用,通常作为配置类的构建和表示分离开来,同时也是将配置类从目标类中隔离出来,Build模式比较常见的实现形式是通过链式调用,使得代码简洁、易懂。

1 0
原创粉丝点击