建造者模式定义
定义:建造者模式是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
先分析模型图上的四大部分:
- Product:产品类,指要创建的复杂对象,通常实现了模板方法模式。
- Builder:抽象建造类,规范产品的组建,一般是由子类实现的。
- ConcreteBuilder:具体建造类,实现抽象建造类定义的方法并返回一个建造好的对象。
- Director:导演类,也就是指挥者,负责安排流程。
实例说明
就拿建造房屋举例吧:这里假设建造两种类型的房屋,别墅和普通房屋;两种类型的建造流程顺序不同;别墅为A-B-C三步,普通房屋为C-B-A三步。
1.首先定义出Product类,VillaModel和OrdinaryhouseModel
(1).抽象产品类
public abstract class HouseModel {
//定义执行的顺序,放在集合内
private List<String> OrderList=new ArrayList<>();
//建造房屋的步骤,不分先后,不同的房屋,顺序不同
protected abstract void buildstepA();
protected abstract void buildstepB();
protected abstract void buildstepC();
/*
建造房屋
*/
final public void build(){
for (int i=0;i<this.OrderList.size();i++){
String name =this.OrderList.get(i);
if (name.equalsIgnoreCase("stepA")){
this.buildstepA();
}else if (name.equalsIgnoreCase("stepB")){
this.buildstepB();
}else if (name.equalsIgnoreCase("stepC")){
this.buildstepC();
}
}
}
//设置顺序
public void setOrderList(List<String> orderList) {
OrderList = orderList;
}
}
(2).两个实现类
public class VillaModel extends HouseModel {
@Override
protected void buildstepA() {
System.out.println("别墅建造步骤A操作");
}
@Override
protected void buildstepB() {
System.out.println("别墅建造步骤B操作");
}
@Override
protected void buildstepC() {
System.out.println("别墅建造步骤C操作");
}
}
public class OrdinaryhouseModel extends HouseModel {
@Override
protected void buildstepA() {
System.out.println("普通房屋建造步骤A操作");
}
@Override
protected void buildstepB() {
System.out.println("普通房屋建造步骤B操作");
}
@Override
protected void buildstepC() {
System.out.println("普通房屋建造步骤C操作");
}
}
2.定义Builder抽象建造类,也就是写两种房屋的建造方式.
public abstract class HouseBuilder {
//为了设置建造顺序
public abstract void setOrderList(List<String> orderList);
//获取安排完建造顺序的对应的房屋
public abstract HouseModel getHouseModel();
}
3.定义ConcreteBuilder具体建造类,也就是两种房屋建造类实现上面定义的Builder
//别墅
public class VillaBuilder extends HouseBuilder {
private VillaModel villaModel=new VillaModel();
@Override
public void setOrderList(List<String> orderList) {
this.villaModel.setOrderList(orderList);
}
@Override
public HouseModel getHouseModel() {
return this.villaModel;
}
}
//普通房屋
public class OrdinaryhouseBuilder extends HouseBuilder {
private OrdinaryhouseModel ordinaryhouseModel=new OrdinaryhouseModel();
@Override
public void setOrderList(List<String> orderList) {
this.ordinaryhouseModel.setOrderList(orderList);
}
@Override
public HouseModel getHouseModel() {
return this.ordinaryhouseModel;
}
}
注意:上面的准备工作都做完了,为了更深刻的理解Director<导演类>,我们先不加Director,直接去实现此实例。
不加入Director类,实现方式就是直接设置顺序,以建造别墅为例,代码如下:
List<String> OrderList=new ArrayList<>();
OrderList.add("stepA");
OrderList.add("stepB");
OrderList.add("stepC");
VillaBuilder villaBuilder=new VillaBuilder();
villaBuilder.setOrderList(OrderList);
VillaModel villaModel= (VillaModel) villaBuilder.getHouseModel();
villaModel.build();
这还只是别墅的建造,代码是不是很臃肿?所以封装是必须的,既加上Director类来指挥(封装)顺序。
4.定义Director类,也就是对已知的两种房屋的建造步骤进行封装
public class Director {
private List<String> OrderList=new ArrayList<>();
private OrdinaryhouseBuilder ordinaryhouseBuilder=new OrdinaryhouseBuilder();
private VillaBuilder villaBuilder=new VillaBuilder();
/*
普通房屋建造步骤封装
*/
public OrdinaryhouseModel getHouseModel(){
this.OrderList.clear();
this.OrderList.add("stepC");
this.OrderList.add("stepB");
this.OrderList.add("stepA");
this.ordinaryhouseBuilder.setOrderList(OrderList);
return (OrdinaryhouseModel) this.ordinaryhouseBuilder.getHouseModel();
}
/*
别墅建造步骤封装
*/
public VillaModel getvillaModel(){
this.OrderList.clear();
this.OrderList.add("stepA");
this.OrderList.add("stepB");
this.OrderList.add("stepC");
this.villaBuilder.setOrderList(OrderList);
return (VillaModel) this.villaBuilder.getHouseModel();
}
}
这时实现实例的代码如下:
Director director=new Director();
director.getHouseModel().build();
director.getvillaModel().build();
运行结果:
加入了Director类后调用是不是感觉很简单,清晰了。另外如果两种房屋的建造步骤有变化了,可以直接在Director类封装新的顺序。
建造者模式应用
1.实用范围
- 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
- 当构造过程必须允许被构造的对象有不同表示时。
2.建造者模式的优缺点
(1).优点
- 封装性好
- 具体建造类之间独立,扩展性好
(2).缺点
产生多余的Build对象以及Dirextor类。
3.建造者模式与工厂模式的区别
这两种模式很相似,建造者模式更注重于方法的调用顺序,而工厂模式注重于创建产品。具体的区别还是推荐大家去亲身去了解一下这两种模式。
文章学习参考了《设计模式之禅》《Android进阶之光》
另外可以加入我的Android技术交流群:458739310
大家可以关注我的微信公众号:「安卓干货铺」一个有质量、有态度的公众号!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。