android 构建者设计模式,Android中的设计模式之构建者模式

参考

《设计模式:可复用面向对象软件的基础 》3.2 Builder 生成器--对象创建型模式

《Android源码设计模式解析与实战》第3章 Builder模式

意图

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

适用性

相同的方法,不同的执行顺序,产生不同的事件结果时。

多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时。

产品类非常复杂,或者产品类中的调用顺序不同产生了不同的作用,这个时候使用建造者模式非常合适。

当初始化一个对象特别复杂,如参数多,且很多参数都具有默认值时。

结构

f7978fbbf773

Builder模式

Product

表示被构造的复杂对象

包含定义组成部件的类,包括将这些部件装配成最终产品的接口

Builder 抽象Builder类,为创建一个Product对象的各个部件指定抽象接口,规范产品的组建,一般是由子类实现具体的组建过程。

ConcreteBuilder 具体的Builder实现类

Director 使用Builder接口进行构造

协作

客户创建Director对象,并用它所想要的Builder对象进行配置。

一旦产品部件被生成,Builder就会通知生成器

生成器处理Builder的请求,并将部件添加到该产品中。

客户从生成器中检索产品

f7978fbbf773

协作序列图

例子1:RTF阅读器

一个RTF(Rich Text Format)阅读器应能将RTF转换为多种正文格式。该阅读器可以将RTF文档转换为普通ASCII文本或者一个能以交互方式编辑的正文窗口组件。但问题是在于可能转换的数目是无限的。因此要能够很容易地实现新的转换的增加,同时却不改变RTF阅读器。

一种解决办法就是运用Builder模式,用一个可以将RTF转换成另一种正文表示的TextConverter对象配置这个RTFReader类。当RTFReader对RTF文档进行语法分析时,它使用TextConverter去做转换。

f7978fbbf773

RTFReader类设计

每种转换器类将创建和装配一个复杂对象的机制隐含在抽象接口的后面。转换器独立于阅读器,阅读器负责对一个RTF文档进行语法分析。

每一个转换器类可以作为生成器builder,而阅读器作为director。Builder模式将分析文本格式的算法与描述怎样创建和表示一个转换后格式的算法分离开来。这使得我们可以重用RTFReader的语法分析算法,分局RTF文档创建不同的正文表示--仅需使用不同的TextConverter的子类配置该RTFReader即可。

例子2:组装电脑

我想随意组装一台电脑,比如一台Inter主板,Retina显示屏,MacOs的电脑

计算机的组装过程较为负复杂,并且组装顺序是不固定的,所以我们可以用Buider模式。

f7978fbbf773

组装电脑

示例代码:

// 电脑基础抽象类

public abstract class Computer {

protected String mBoard;

protected String mDisplay;

protected String mOS;

protected Computer(){}

//设置主板

public void setBoard(String board){

this.mBoard=board;

}

//设置显示器

public void setDisplay(String display) {

mDisplay=display;

}

//设置操作系统

public abstract void setOS();

@Override

public String toString() {

StringBuilder stringBuilder=new StringBuilder();

if (mBoard!=null) {

stringBuilder.append("myBoard is:"+mBoard);

}

if (mDisplay!=null) {

stringBuilder.append("\nmDisplay is:"+mDisplay);

}

if (mOS!=null) {

stringBuilder.append("\nmyOS is:"+mOS);

}

return stringBuilder.toString();

}

}

//Macbook电脑,实现了setOs

public class MacBook extends Computer{

@Override

public void setOS() {

mOS="Mac _S X 10.10";

}

}

// 抽象Builder

public abstract class Builder{

abstract Buider buildBoard(String board);

abstract Buider buildDisplay(String display);

abstract Buider buildOS();

abstract Computer create();

}

//具体的一个Builder类

public class MacBookBuilder extends Buider {

private Computer mComputer=new MacBook();

@Override

public Buider buildBoard(String board) {

mComputer.setBoard(board);

return this;

}

@Override

public Buider buildDisplay(String display) {

mComputer.setDisplay(display);

return this;

}

@Override

public Buider buildOS() {

mComputer.setOS();

return this;

}

@Override

public Computer create() {

return mComputer;

}

}

// Director类,负责构造Computer

public class Director{

Builder mBuilder = null;

public Director(Builder builder){

mBuilder = builder;

}

public void construct(String board,String display){

mBuilder.buildBoard(board);

mBuilder.buildDisplay(display);

mBuilder.buildOs();

}

}

//使用

public static void main(String[] args) {

Builder macBookBuilder=new MacBookBuilder();

Director director = new Director(macBookBuilder);

// 使用Director构造

director.construct(英特尔主板,retina);

System.out.println(macBookBuilder.create().toString())

// 通常我们都会通过Builder的链式调用省略Director类,比如如下所示

System.out.println(macBookBuilder.buildBoard("英特尔主板")

.buildDisplay("retina")

.buildOS()

.create().toString());

}

结果:

myBoard is:英特尔主板

mDisplay is:retina

myOS is:Mac _S X 10.10

效果

它使你可以改变一个产品的内部表示

它将构造代码和表示代码分开

它使你可对构造过程进行更精细的控制

《Effective java》书中建议如果构造一个对象复杂,需要传入很多参数,不妨采用Builder模式,有效减少了传参失误。

当然缺点是增加了代码量。

例子3 Android中的AlertDialog.Builder

// todo 后更

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值