您的位置:首页 > 产品设计 > UI/UE

Android Builder模式详解

2016-12-19 01:31 489 查看
经典Builder模式

1) 定义:将一个复杂对象的构建与它的表示分离,使得同样

的构建过程可以创建不同的表示。



2) 经典的Builder模式有四个参与者

Product:被构造的复杂对象

Builder:抽象接口,用来定义创建Product对象的各个组成部

件的操作。

ConcreteBuilder:Builder接口的具体实现,可以定义多个,

是实际构建Product对象的类,同时会提供一个返回Product的接

口。

Director:Builder接口的构造者和使用者。

3) 简单代码形式

public class Product {
private String mName;
private int mAge;

public String getmName() {
return mName;
}

public void setmName(String mName) {
this.mName = mName;
}

public int getmAge() {
return mAge;
}

public void setmAge(int mAge) {
this.mAge = mAge;
}
}


public interface Builder {
void buildName();

void buildAge();

Product getProduct();
}


public class ConcreteBuilder implements Builder {
private Product mProduct;

@Override
public void buildName() {

}

@Override
public void buildAge() {

}

@Override
public Product getProduct() {
return mProduct;
}
}


public class Director {
private Builder mBuilder;

public Director(Builder builder) {
mBuilder = builder;
}

public void buildProduct() {
mBuilder.buildName();
mBuilder.buildAge();
}

public Product getProduct() {
return mBuilder.getProduct();
}
}


4) 经典的Builder模式重点在于抽象出对象创建的步骤,并通过调

用不同的具体实现从而得到不同的、

Builder模式的变种(Android Builder模式)

1) 变种的Builder模式的目的在于减少对象创建过程中引用的多

个重载构造方法、可选参数和setters过度使用导致的不必要的复

杂性。下面以一个简单对象Person对象创建过程为例子说明,它

具有如下所示的属性,且都是不可变的final的。

public class Person{
private final String mName;    //必选
private final int mAge;        //必选
private final int mGender;      //必选
private final String mAddress; //可选
}


由于已经将属性声明为final,因此必须在构造函数中对属性进行

赋值,由于属性有必选和可选之分,也就是说构造方法需要提供

可以选择忽略可选参数的方式。两种方案如下代码所示:

构造方法初始化

public Person(String name,int age,int gender){
this(name,age,gender,"")
}

public Person(String name,int age,int
gender,String address){
mName = name;
mAge = age;
mGender = gender;
mAddress = address;
}


JavaBeans规范(无参构造方法,提供getters和setters方法)

public class Person {
private String mName;
private int mAge;
private int mGender;
private String mAddress;

public String getmName() {
return mName;
}

public void setmName(String mName) {
this.mName = mName;
}

public int getmAge() {
return mAge;
}

public void setmAge(int mAge) {
this.mAge = mAge;
}

public in
4000
t getmGender() {
return mGender;
}

public void setmGender(int mGender) {
this.mGender = mGender;
}

public String getmAddress() {
return mAddress;
}

public void setmAddress(String mAddress) {
this.mAddress = mAddress;
}


JavaBeans方案的好处是易于阅读和维护,使用Person只需要

创建实例对象,调用setters方法设置必要的属性即可。但这样

做存在两个缺点:Person类是可变的;Person类是不连续状态

的(只有所有的setters方法被调用后,才是连续状态)。

那么怎样才可以具有前面方案的优点,又不存在它们的缺点呢

?(变种的Builder模式Android Builder模式)

2) Builder模式的变种(Android Builder模式)

```
public class Person {
private final String mName;
private final int mAge;
private final int mGender;
private final String mAddre;

private Person(Builder builder) {
mName = builder.mName;
mAge = builder.mAge;
mGender = builder.mGender;
mAddre = builder.mAddre;
}

public int getmAge() {
return mAge;
}

public int getmGender() {
return mGender;
}

public String getmName() {
return mName;
}

public String getmAddre() {
return mAddre;
}

public static final class Builder {
private String mName;
private int mAge;
private int mGender;
private String mAddre;

public Builder(String name, int age,
int gender) {
mName = name;
mAge = age;
mGender = gender;
}

public Builder mAddre(String val) {
mAddre = val;
return this;
}

public Person build() {
return new Person(this);
}
}
}
```


Person类的构造方法是私有的,不可以直接通过new来创建实例

Person类是不可变的,对属性值只提供getter方法

最后,创建一个Person对象

```
public Person getPerson() {
return new Person.Builder("Wxq", 23, 1)
.mAddre("China")
.build();
}
```


Android Studio自动生成变种Builder模式



安装好后重启Android Studio,只需要把属性名确定下来,alt键+insert键,选择builder按钮即可(快捷键Alt+Shift+B)。



Android中使用Builder模式的例子

1)系统对话的使用Builder模式

```
public void showDialog() {
AlertDialog alertDialog = new AlertDialog.Builder(this)
.setTitle("对话框")
.setMessage("测试")
.setIcon(R.mipmap.ic_launcher)
.create();
alertDialog.show();
}
```
2) ImageLoader使用Builder模式

```
private void initImageLoader() {
ImageLoaderConfiguration.Builder config = new
ImageLoaderConfiguration.Builder(getContext());
config.threadPriority(Thread.NORM_PRIORITY - 2);
config.denyCacheImageMultipleSizesInMemory();
config.memoryCacheSize(5 * 1024 * 1024);// 5M
config.tasksProcessingOrder(QueueProcessingType.LIFO);
ImageLoader.getInstance().init(config.build());
}
```
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息