其实设计模式,只是一种定式,适用于不同的语音,今天,虽然加上了Andorid的前缀,只是因为举例仅是android代码,所以学好内在,则举例仅是举例,内涵才是到处通用的。
建造者模式解释:
建造者模式(Builder Pattern)又叫生成器模式,是GoF提出的23种设计模式中的一种。
建造者模式是一种对象创建型模式之一,用来隐藏复合对象的创建过程,它把复合对象的创建过程加以抽象,通过子类继承和重载的方式,动态地创建具有复合属性的对象。
英文定义为:Separate the construction of a complex object from its representation so that the same construction process can create different representations.
建造者模式涉及以下的角色:
抽象建造者(Builder)角色:给出一个抽象接口,以规范产品对象的各个组成成分的建造。此接口中一般至少规定两个方法,一个是创建部分的方法,例如BuilderPart,另一个是返回结果的方法,例如GetProduct,以约束具体建造者实现。
具体建造者(ConcreteBuilder)角色:担任这个角色的是与应用程序紧密相关的一些类,它们在应用程序的调用下创建产品的实例。这个角色产品实现了抽象建造者接口,主要完成分步创建产品并提供产品对象的实例。
导演者(Director)角色:顾名思义,就是具体指挥使用哪个具体创造者来完成产品的创建,是创建工作的调用者。但是,导演者角色并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者角色。
产品(Product)角色:产品角色就是建造中的复杂对象。一般只有对于复杂对象的创建才使用建造者模式,一个系统中会出现多于一个的产品类,而这些产品类并不一定有共同的接口,可能完全不关联,这时就需要提供多套抽象和具体的建造者来完成不一致的产品的创建或者是采用一个统一接口来标识产品。
建造者模式的UML图如下所示:
建造者模式深入分析:
在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法确相对稳定。如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?这就是要说的建造者模式。
建造者模式将复杂对象的构建与对象的表现分离开来,这样使得同样的构建过程可以创建出不同的表现。
建造者模式使用场景分析及代码实现:
一个人有姓名、性别、年龄、身高,体重这五个属性组成,当我们创建一个人这个对象的时候,我们可能有下面这些情况:
1、只希望指定姓名
2、只希望指定性别
3、只希望指定年龄
4、只希望指定身高
5、只希望指定体重
6、只希望指定姓名和性别
7、只希望指定姓名和年龄
8、只希望指定姓名和身高
9、只希望指定姓名和体重
10、只希望指定性别和年龄
11、只希望指定性别和身高
12、……
上面就不一样列举了,就是一个排列组合问题,是不是有些凌乱了,如果一个对象的属性更多,那情况就更多了,显然把所以执行情况的构造函数都写出来不是一个明智的选择,因为想想你要写多少个构造函数,好恐怖,不敢想象。
那我们有没有一种方法来解决这个问题呢?这里我们就要使用建造者模式,它就是单独的来对一个对象进行构造,将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。也就是说它来完成对象的构造过程,并且这个过程可以构造出上面我们所说的所有我们希望得到的对象。
建造模式是将复杂的内部创建封装在内部,对于外部调用的人来说,只需要传入建造者和建造工具,对于内部是如何建造成成品的,调用者无需关心。
针对上面所说的那个包含了5个属性的对象,我们使用构建者模式如何完成,下面我们来看看。
1、定义一个Person类,他包含了所有属性的get,set方法。
public class Person {
private String name;
private boolean sex;
private int age;
private float height;
private float weight;
public Person(String name, boolean sex, int age, float height, float weight) {
this.name = name;
this.sex = sex;
this.age = age;
this.height = height;
this.weight = weight;
}
}
2、创建一个Builder类
public class Builder {
private String name;
private boolean sex;
private int age;
private float height;
private float weight;
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setSex(boolean sex) {
this.sex = sex;
return this;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Builder setHeight(float height) {
this.height = height;
return this;
}
public Builder setWeight(float weight) {
this.weight = weight;
return this;
}
public Person create() {
return new Person(name, sex, age, height, weight);
}
}
上面我们就写好了这个构造过程了。现在就可以根据我们的需要来得到任何我们想要的对象。
Builder builder = new Builder();
builder.setName("Mirhunana");
builder.setAge(23);
Perons person = builder.create();
上面我们就得到了一个我们想要的对象,很方便,很简单。
下面为了说明这个完整的过程,我们对上面我们写的那个构建者模式进行改进。
1、产品类Product
就是上面的Person
2、抽象建造者类Builder,就是上面的Builder的接口,目的就是为了为构造者提供统一的接口
public interface Builder {
public Builder setName(String name);
public Builder setSex(boolean sex);
public Builder setAge(int age);
public Builder setHeight(float height);
public Builder setWeight(float weight);
public Person create();
}
3、 具体建造者类ConcreteBuilder,就是前面的Builder,只是它实现了一个共同的Builder接口
public class ConcreteBuilder implements Builder {
private String name;
private boolean sex;
private int age;
private float height;
private float weight;
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setSex(boolean sex) {
this.sex = sex;
return this;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Builder setHeight(float height) {
this.height = height;
return this;
}
public Builder setWeight(float weight) {
this.weight = weight;
return this;
}
public Person create() {
return new Person(name, sex, age, height, weight);
}
}
4、导演者类Director,它就是操作builder对象的
public class Director {
private Builder builder;
public Director(Builder builder){
this.builder = builder;
}
public void construct(String name, boolean sex, int age, float height, float weight) {
builder.setName(name);
builder.setSex(sex);
builder.setAge(age);
builder.setHeight(height);
builder.setWeight(weight);
}
}
5、客户端代码
public class Test {
public static void main(String[] args) {
Builder builder = new ConcreteBuilder();
Director pcDirector = new Director(builder);
pcDirector.construct("Mirhunana", true, 23, 180, 100);
Person person = builder.create();
}
}
建造者模式的优缺点分析:
优点:
在建造者模式中,客户端不用在直接负责对象的创建,而是把这任务交给了具体的创建者类,把具体的如何组装的责任交给了Director类,客户端之负责对象的调用即可,符合单一职责原则。而且由于可以选择不同的具体的创建者,所以可以有不同的形式展现对象。
缺点:
创建者模式比较符合产品差别不大的对象的创建,如果差别很大,就会导致非常多的具体的创建者,这时候最好结合工厂方法模式。
建造者模式的实际应用简介:
对象的创建:Builder模式是为对象的创建而设计的模式
创建的是一个复合对象:被创建的对象为一个具有复合属性的符合对象
关注对象创建各部分的创建过程,不同的工厂对产品的属性有不同的创建的方法。
温馨提示:
建造者模式是为了解决复合对象的创建而生的,建造者模式将复杂对象的构建与对象的表现分离开来,这样使得同样的构建过程可以创建出不同的表现。有利明确各部分的职责目标,有利于软件结构的优化。
---------------------------------------------------------------------------------------------------------------------------
Android中的构建者模式,最经典的就是AlertDialog了。