一、概述
设计模式是我们在平时编程的过程中对一些常见的问题场景总结出来的最优编程套路,按照设计模式的思想,我们在编程的过程中遇到类似的问题时可以快速的套用对应的设计模式,从而高效的解决问题。在平时的开发过程中,我们也经常接触到各种设计模式,甚至我们自己写的代码也会不自觉的使用到设计模式,只是可能叫不出名字而已。下来介绍一种Android中常用的设计模式,Builder模式。
二、Builder模式的定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的展示。
Build模式主要的作用是将复杂对象的构建单独剥离出来,通过Builder模式可以减少构造器或者方法调用传入的参数个数,使复杂对象的构建变得清晰,这对有很多配置参数进行初始化的对象尤其适用。
三、实例分析
下面我们定义一个Person类,结构如下:
public class Person {
private String name;
private int age;
private double weight;
private double height;
}
为了构造Person对象,我们提供了以下构造函数
public Person() {
}
public Person(String name) {
this.name = name;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name, int age, double weight) {
this.name = name;
this.age = age;
this.weight = weight;
}
public Person(String name, int age, double weight, double height) {
this.name = name;
this.age = age;
this.weight = weight;
this.height = height;
}
或者提供一系列的set方法
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setWeight(double weight) {
this.weight = weight;
}
public void setHeight(double height) {
this.height = height;
}
现在我们有两种方式去构造对象并且设置参数,一种是直接调用构造函数将参数传入,一种是调用set方法设置参数,或者两种混合使用,如下:
Person person = new Person("张三");
Person person1 = new Person("李四", 18);
Person person2 = new Person("王五", 20, 100);
Person person3 = new Person("刘六", 25, 120, 180);
Person person4 = new Person();
person4.setName("邓七");
person4.setAge(23);
person4.setWeight(130);
person4.setHeight(175);
先说说使用构造函数的方式,使用构造函数的方式不仅添加了很多构造函数,而且很难区分构造函数中每一个参数的具体含义,我们必须找到对应的构造函数的实现才能明白每一个参数的意义;再说使用set的方式,我们在使用set来设置对象的属性之前,这个对象已经构建出来了,我们在代码中是可以直接使用的,这样就可能造成错误,也就是这个对象的构建和初始化时分离的,但其实,初始化和对象的构建应该绑定在一起,构建完成后立马就应该初始化。
解决上面问题的办法就是使用Builder模式,代码如下:
public class Person {
private String name;
private int age;
private double weight;
private double height;
private Person(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.weight = builder.weight;
this.height = builder.height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public static class Builder {
private String name;
private int age;
private double weight;
private double height;
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Builder setWeight(double weight) {
this.weight = weight;
return this;
}
public Builder setHeight(double height) {
this.height = height;
return this;
}
public Person build() {
Person person = new Person(this);
return person;
}
}
}
构建对象:
Person person = new Person.Builder().
setName("张三").
setAge(17).
setWeight(110).
setHeight(180).
build();
构建模式专门创建了一个静态内部类来帮助对象的构建,先构建一个静态内部类的对象,然后通过链式调用的形式将参数设置给静态内部类对象,设置完成后,调用静态内部类的build方法去构建实际要构建的对象,通过这种方式,我们能够在对象构建之前就将构建参数全部设置完毕,而且使用链式调用的方式,代码结构清晰易懂。
四、Android中使用Builder模式的实例
在Android系统和各大框架中,我们都不难看到Builder模式的身影,下面列举几个:
1、AlertDialg
AlertDialog alertDialog = new AlertDialog.Builder(this).
setTitle("标题").
setIcon(R.mipmap.ic_launcher).
setView(R.layout.support_simple_spinner_dropdown_item).
setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
}).
setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
}).
create();
alertDialog.show();
2、OkHttp中的Request对象构建
Request.Builder builder=new Request.Builder();
Request request=builder.addHeader("","")
.url("")
.post(body)
.build();
3、Gson中Gson对象的构建
GsonBuilder builder=new GsonBuilder();
Gson gson=builder.setPrettyPrinting()
.disableHtmlEscaping()
.generateNonExecutableJson()
.serializeNulls()
.create();
四、总结
1、Builder模式是为了解决复杂对象的构建,将复杂对象的构建单独剥离出来,可以减少构造构造器和参数,Builder模式先设置构建参数,再构建对象的实例的,这样能够有效的避免对象没有初始化的问题;
2、先定义一个Builder静态内部类,属性和外部类保持一致;
3、给Builder类提供一系列的set方法设置属性,返回Builder类本身;
4、外部类提供一个私有的构造方法,参数为Builder对象,用Builder对象的属性给外部类属性赋值;
5、Builder类提供一个build方法,build方法中利用外部类提供的私有构造方法构造外部类对象并返回,参数为Builder类本身;
6、程序获得外部类对象时,要先构建对应的Builder类对象,然后调用Builder类的一系列set方法设置属性,最后调用build方法生成外部类对象。