Android设计模式-建造者模式

来源:互联网 发布:iphone写日记的软件 编辑:程序博客网 时间:2024/05/16 17:30

相当多的开发者使用过ImageLoader这个库,首先需要配置:

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)          .memoryCacheExtraOptions(480, 800) // default = device screen dimensions          .diskCacheExtraOptions(480, 800, CompressFormat.JPEG, 75, null)          .threadPoolSize(3) // default          .denyCacheImageMultipleSizesInMemory()          .memoryCache(new LruMemoryCache(2 * 1024 * 1024))          .memoryCacheSize(2 * 1024 * 1024)          .memoryCacheSizePercentage(13) // default          .diskCache(new UnlimitedDiscCache(cacheDir)) // default          .diskCacheSize(50 * 1024 * 1024)          .diskCacheFileCount(100)        .writeDebugLogs()          .build();  

又或者我们安卓常用的AlertDialog也是使用这种模式创建出来的。在使用ImageLoader的时候,我们只需要配置需要自定义的参数就行了,不配置的就按照默认的构造,使用起来非常的方便。

建造者模式顾名思义,假如我们需要建一个房子,但是我们不会建房子,所以我们找来一个包工头他是指导者(Director),包工头负责指挥工人具体建造者(Concrete Builder),工人按照图纸(建造者Builder即一个抽象接口),有的负责打地基,有的和泥,有的搬砖···,最后盖完一个房子(产品 Product)。你得到了房子,并不需要了解房子怎么盖。

从技术角度来说,建造者模式的定义:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式的应用场景(其中2,3,4点参考自Android源码与设计模式这本书):

  • 初始化参数非常多,但是必须的参数很少,大部分都有默认值,前面的ImageLoader就是这样的情况
  • 相同的方法,不同的执行顺序,产生不同的事件结果时
  • 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时
  • 产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式非常合适
    如果还有其他场景适合使用建造者模式欢迎补充。

    角色介绍:

  • 建造者(Builder)角色:给出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此接口独立于应用程序的商业逻辑。模式中直接创建产品对象的是具体建造者(Concrete Builder)角色。具体建造者类必须实现这个接口所要求的方法:一个是建造方法,另一个是结果返还方法。

  • 具体建造者(Concrete Builder)角色:担任这个角色的是于应用程序紧密相关的类,它们在应用程序调用下创建产品实例。这个角色主要完成的任务包括:实现Builder角色提供的接口,一步一步完成创建产品实例的过程。在建造过程完成后,提供产品的实例。
  • 指导者(Director)角色:担任这个角色的类调用具体建造者角色以创建产品对象。导演者并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者对象。
  • 产品(Product)角色:产品便是建造中的复杂对象。指导者角色是于客户端打交道的角色。导演者角色将客户端创建产品的请求划分为对各个零件的建造请求,再将这些请求委派给具体建造者角色。具体建造者角色是做具体建造工作的,但却不为客户端所知。

    代码是最好的老师,情景是我们要生产一辆汽车,上代码:
    首先是产品Product:

public abstract class Car {    protected String engine;    protected String tyres;    protected String logo;    protected Car(){    }    // 设置发动机    protected void setEngine(String engine) {        this.engine = engine;    }    // 设置轮胎    protected void setTyres(String tyres) {        this.tyres = tyres;    }    // 设置车架    protected abstract void setLogo();    @Override    public String toString() {        return "Car [Engine=" + engine + ", Tyres=" + tyres                + ", logo=" + logo + "]";    }}

这个类就是汽车的一个基类,有发动机,轮胎,车标属性。

public class Benz extends Car {    @Override    protected void setLogo() {        this.logo = "奔驰";    }}

这是一辆奔驰汽车。

public abstract class Builder {    //设置轮胎    public abstract Builder buildTyres(String tyres);    //设置车标    public abstract Builder buildLogo();    //构建Car    public abstract Car create();}

这个是构建者的类,可以理解为图纸,规范产品对象的各个组成成分的建造。

public class CarBuilder extends Builder {    private Car car;    public CarBuilder(String engine) {        car = new Benz();        car.setEngine(engine);    }    @Override    public CarBuilder buildTyres(String tyres) {        car.setTyres(tyres);        return this;    }    @Override    public CarBuilder buildLogo() {        car.setLogo();        return this;    }    @Override    public Car create() {        return car;    }}

具体建造者,这个相当于组装的真正车间。我们这个例子中,假如发动机是必须的参数,而其他是可选的。

public class Director {    Builder builder;    public Director(Builder builder) {        this.builder = builder;    }    public void construct(String tyres) {        builder.buildTyres(tyres);        builder.buildLogo();    }}

指导者,在construct方法中,负责指挥具体的建造者完成构建。

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //第一种,现实中更常用        Car car = new CarBuilder("V12 发动机").buildTyres("倍耐力").buildLogo().create();        Log.i("car1", car.toString());        //第二种        Builder builder = new CarBuilder("V8 发动机");        Director director = new Director(builder);        director.construct("米其林");        Log.i("car2", builder.create().toString());    }}

每个构建者都必须指定发动机,第一种方法在我们平时开发中更加常见,也更加方便。打印的结果:

car1: Car [Engine=V12 发动机, Tyres=倍耐力, logo=奔驰]car2: Car [Engine=V8 发动机, Tyres=米其林, logo=奔驰]
1 0
原创粉丝点击