Builder模式基本介绍
在我们的项目中,常常会遇到较为复杂的对象,如果使用传统的set方法来构造这个对象。开发成本和维护成本便会急速上升。Builder模式则是一步一步创建一个复杂对象的创建型模式。它允许用户在不知道内部构建细节的情况下,可以更精确的控制对象的构造流程。
Builder模式的UML图
Product —– 产品类
Builder —– Builder抽象类,一般是由子类实现具体的组建过程
ConcreteBuilder —- 具体的Builder类
Director —– 统一组装过程
Builder模式的定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
简单的代码实现
package com.lpoint.builder;
//构建一个Product的抽象类
public abstract class Person {
protected String name;
protected String sex;
protected int age;
protected Person(){
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public abstract void setSex();
@Override
public String toString() {
return "[" + name + "]:Age is " + age + ",sex is " + sex + ";";
}
}
package com.lpoint.builder;
//创建一个具体的Product类
public class Student extends Person{
protected Student(){
}
@Override
public void setSex() {
sex = "F";
}
}
package com.lpoint.builder;
//Builder的抽象类
public abstract class Builder {
public abstract Builder builderName(String name);
public abstract Builder builderSex();
public abstract Builder builderAge(int age);
//创建具体的对象
public abstract Person create();
}
package com.lpoint.builder;
//具体的Builder类
public class StudentBuilder extends Builder{
private Person p = new Student();
@Override
public StudentBuilder builderName(String name) {
p.setName(name);
return this;
}
@Override
public StudentBuilder builderSex() {
p.setSex();
return this;
}
@Override
public StudentBuilder builderAge(int age) {
p.setAge(age);
return this;
}
@Override
public Person create() {
return p;
}
}
package com.lpoint.builder;
public class Test {
public static void main(String[] args) {
Builder builder = new StudentBuilder();
Person s = builder.builderAge(15)
.builderName("Lisa")
.builderSex()
.create();
System.out.println(s.toString());
}
}
通过上面这些简单的代码,我们在客户端先实例化了一个Builder对象,然后通过builder的一些方法,来创建出了一个Person对象。注意这里我们去除了Director这个角色,其实实际开发我们更多的是这样放弃Director对象而采取对Builder对象的链式调用来创建对象的,这样子结构明显更加简单清晰,具体的初始化过程也都在builder对象里面被封装了。客户端只需要调用builder的方法并在最后create就好了。
Android里面Builder模式的应用
相信很多同学看到了最后客户端对Builder的链式调用,一定能够发现在Android里面也有很多相同的操作,最典型的便是Dialog对象的构建。在一些第三方库也会有类似的操作,比如著名的Universal-Image-Loader,有兴趣的同学大可以去研究一下他们的源码来加深自己对Builder模式的理解,这里不做赘述。
小结
我们在实际的项目开发中,经常就会遇到这样复杂的对象构建,而且很多不光是对象自己复杂,对象的使用环境也会遇到较为复杂的时候。为了避免对象对外暴露过多的结构而增加开发和代码的维护难度,就可以通过这种Builder模式来将复杂对象的构建和配置方法封装起来,对外只暴露可以链式调用的Builder方法。当然万事有利皆有弊。我们简单看一下Builder模式的优缺点。
优点
1.良好的封装性,使用建造者模式可以使客户端不必知道产品内部组成的细节。
2.建造者独立,容易扩展。
缺点
会产生多余的Builder对象,消耗了更多的内存。