Android 设计模式 之 建造者模式

一 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模式比较常见的实现形式是通过链式调用,使得代码简洁、易懂。



转载自:http://blog.csdn.net/happy_horse/article/details/51168680

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值