描述
建造模式是对象的创建模式。建造模式可以将一个产品的内部表象与产品的生产过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。
简介
建造者类图建造者模式是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
一个产品常有不同的组成成分作为产品的零件,这些零件有可能是对象,也有可能不是对象,它们通常又叫做产品的内部表象(internal representation)。不同的产品可以有不同的内部表象,也就是不同的零件。使用建造模式可以使客户端不需要知道所生成的产品有哪些零件,每个产品的对应零件彼此有何不同,是怎么建造出来的,以及怎么组成产品。
角色
-
抽象建造者(Builder)角色:给出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此接口独立于应用程序的商业逻辑。模式中直接创建产品对象的是具体建造者 (ConcreteBuilder)角色。具体建造者类必须实现这个接口所要求的两种方法:一种是建造方法(buildPartA和 buildPartB),另一种是返还结构方法(retrieveResult)。一般来说,产品所包含的零件数目与建造方法的数目相符。换言之,有多少零件就有多少相应的建造方法。
-
具体建造者(ConcreteBuilder)角色:担任这个角色的是与应用程序紧密相关的一些类,它们在应用程序调用下创建产品的实例。这个角色要完成的任务包括:1.实现抽象建造者Builder所声明的接口,给出一步一步地完成创建产品实例的操作。2.在建造过程完成后,提供产品的实例。
-
导演者(Director)角色:担任这个角色的类调用具体建造者角色以创建产品对象。应当指出的是,导演者角色并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者角色。
-
产品(Product)角色:产品便是建造中的复杂对象。一般来说,一个系统中会有多于一个的产品类,而且这些产品类并不一定有共同的接口,而完全可以是不相关联的。
优缺点
优点
-
产品的建造和表示分离,实现了解耦。
-
隐藏了产品的建造细节,用户只需关心产品的表示,而不需要了解是如何创建产品的。
-
体现了开闭原则,如上代码所示,如果需要再生产其他共享单车,只需要再开一条生产线即可,不影响其他生产线的作业。
缺点
-
产品必须有共同点,范围有限制。
-
如内部变化复杂,会有很多的建造类,难以维护。
使用场景
-
需要生成的产品对象有复杂的内部结构,每一个内部成分本身可以是对象,也可以仅仅是一个对象(即产品对象)的一个组成部分。
-
需要生成的产品对象的属性相互依赖。建造模式可以强制实行一种分步骤进行的建造过程,因此,如果产品对象的一个属性必须在另一个属性被赋值之后才可以被赋值,使用建造模式是一个很好的设计思想。
-
在对象创建过程中会使用到系统中的其他一些对象,这些对象在产品对象的创建过程中不易得到。
示例
我们用制造自行车为例子讲解建造者模式,自行车由车架、轮胎、脚踏等部件组成。自行车制造公司就是把这些零部件组装起来。自行车制造公司的工程部门相当于指挥者,生产部门相当于建造者,当今共享单车做的比较大的摩拜和ofo相当于客户,单车就是产品了。
/**
* 产品(Product)角色
* 单车产品
*/
public class Bike {
/**
* 轮胎
*/
private String tyre;
/**
* 车架
*/
private String frame;
/**
* GPS定位装置
*/
private String gps;
public String getTyre() {
return tyre;
}
public void setTyre(String tyre) {
this.tyre = tyre;
}
public String getFrame() {
return frame;
}
public void setFrame(String frame) {
this.frame = frame;
}
public String getGps() {
return gps;
}
public void setGps(String gps) {
this.gps = gps;
}
@Override
public String toString() {
return "Bike{" +
"tyre='" + tyre + '\'' +
", frame='" + frame + '\'' +
", gps='" + gps + '\'' +
'}';
}
}
/**
* 抽象建造者(Builder)角色
* 自行车生产线接口
*/
public interface BikeBuilder {
/**
* 组装轮胎
*/
void buildTyres();
/**
* 组装车架
*/
void buildFrame();
/**
* 组装GPS定位装置
*/
void buildGPS();
/**
* 获取自行车
*/
Bike getBike();
}
/**
* 具体建造者(ConcreteBuilder)角色
* 摩拜单车
*/
public class MoBikeBuilder implements BikeBuilder {
/**
* 单车对象
*/
private Bike bike;
public MoBikeBuilder(Bike bike) {
this.bike = bike;
}
@Override
public void buildTyres() {
bike.setTyre("橙色轮胎");
}
@Override
public void buildFrame() {
bike.setFrame("橙色车架");
}
@Override
public void buildGPS() {
bike.setGps("mobike定制版GPS定位装置");
}
@Override
public Bike getBike() {
return bike;
}
}
/**
* 具体建造者(ConcreteBuilder)角色
* OfO单车
*/
public class OfoBikeBuilder implements BikeBuilder {
/**
* 单车对象
*/
private Bike bike;
@Override
public void buildTyres() {
bike.setTyre("黑色轮胎");
}
@Override
public void buildFrame() {
bike.setFrame("黄色车架");
}
@Override
public void buildGPS() {
bike.setGps("ofo定制版GPS定位装置");
}
@Override
public Bike getBike() {
return bike;
}
}
/**
* 导演者(Director)角色
* 指导组装单车
*/
public class EngineeringDepartment {
private BikeBuilder bikeBuilder;
/**
* 用户告知指挥者想要什么样的单车
*
* @param bikeBuilder
*/
public EngineeringDepartment(BikeBuilder bikeBuilder) {
this.bikeBuilder = bikeBuilder;
}
/**
* 指导组装单车
*/
public void construct() {
bikeBuilder.buildTyres();
bikeBuilder.buildFrame();
bikeBuilder.buildGPS();
}
}
/**
* 测试类
*/
public class BuilderTest {
public static void main(String[] args) {
Bike bike = new Bike();
/**
* 创建摩拜单车
*/
BikeBuilder bikeBuilder = new MoBikeBuilder(bike);
EngineeringDepartment engineeringDepartment = new EngineeringDepartment(bikeBuilder);
/**
* 指导组装单车
*/
engineeringDepartment.construct();
System.out.println(bike.toString());
}
}
网友评论