一、概述:
将一个复杂对象的构建与它的表示分离,使得同样的构造过程可以创建不同的表示。
二、结构:
1、Product(复杂的产品对象):一个复杂对象,包含多个成员变量。
public class Product(){
private String PartA;
private String PartB;
private String PartC;
//三个成员变量的setter()和getter()省略。
}
2、Builder(建造者):声明两类方法,一类负责创建复杂对象中的各个部件,另一类负责返回复杂对象(即Product)。
public abstract class Builder(){
Product product=new Product();
//1.各个部件的创建方法声明
public abstract void buildPartA();
public abstract void buildPartB();
public abstract void buildPartC();
//2.返回复杂对象
public Product getResult(){
return product;
}
}
3、ConcreteBuilder(具体建造者):继承或实现Builder,覆写Builder中的方法,各个部件的具体实现。
public class ConcreteBuilder extends Build(){
public void buildPartA(){
product.setPartA("A111");
}
public void buildPartB(){
product.setPartA("B111");
}
public void buildPartC(){
product.setPartA("C111");
}
}
4、Director(指挥者):指挥一个复杂对象的构建,包括构建的流程。
public class Director(){
//创建方法,以Builder抽象类作为方法参数
public Product buildProduct(Builder b){
//建造过程:A->B->C
b.buildPartA();
b.buildPartB();
b.buildPartC();
//调用返回复杂对象的方法,将建造后的对象进行返回。
Product p=b.getResult();
}
}
三、应用实例:
某公司要开发一个视频播放软件,提供多种显示模式,如完整模式,精简模式,记忆模式等。不同模式下,显示有所差别。在完整模式下将显示主窗口,菜单,播放列表,控制条;在精简模式下将显示主窗口和控制条;在记忆模式下将显示主窗口,播放列表,控制条。请用建造者模式设计。
-
分析:
复杂产品对象:视频播放软件(VideoPlayer)
抽象Builder:显示部件(Display)
具体Builder:
(1)完整模式Builder(FullMode)
(2)精简模式Builder(SimpleMode)
(3)记忆模式Builder(MemoryMode)
指挥者Director:(BuilderController) -
实例类图:
-
实现(主要代码):
(1)抽象Builder:
public abstract class Display {
protected VideoPlayer videoPlayer=new VideoPlayer();
//声明建造方法
public abstract void buildMenu();
public abstract void buildPlayList();
public abstract void buildMainWin();
public abstract void buildControlBar();
//返回复杂产品对象
public VideoPlayer getVideoPlayerBean(){
return videoPlayer;
}
//钩子方法,对复杂对象构建进行精细的控制
public boolean isNeedMenu(){
return true;
}
public boolean isNeedPlayList(){
return true;
}
public boolean isNeedMainWin(){
return true;
}
public boolean isNeedControlBar(){
return true;
}
}
(2)具体一个Builder:
public class SimpleMode extends Display {
@Override
public void buildMenu() {
videoPlayer.setMenu("精简模式菜单显示了");
}
@Override
public void buildPlayList() {
videoPlayer.setPlayList("精简模式播放列表显示了");
}
@Override
public void buildMainWin() {
videoPlayer.setMainWin("精简模式主窗口显示了");
}
@Override
public void buildControlBar() {
videoPlayer.setControlBar("精简模式控制条显示了");
}
public boolean isNeedMenu(){
return false;
}
public boolean isNeedPlayList(){
return false;
}
}
(3)指挥者:
public class BuildController {
public VideoPlayer buildIt(Display display){
if(display.isNeedMainWin()){
display.buildMainWin();
}
if(display.isNeedMenu()){
display.buildMenu();
}
if (display.isNeedPlayList()){
display.buildPlayList();
}
if (display.isNeedControlBar()){
display.buildControlBar();
}
//上述的构建过程执行完毕之后,返回复杂对象
VideoPlayer videoPlayerBean = display.getVideoPlayerBean();
return videoPlayerBean;
}
}
四、总结:
- 建造者的核心在于如何一步步构建一个包含多个组成部件的完整对象,使用相同的建造过程构建不同的产品。好比如,如何去构建一个英雄角色,需要给它脸型,服装,武器等等,从头到武器的一个建造过程,却可以建造不同的英雄角色。如天使(精致,天使尾翼,星月杖),恶魔(丑陋,蝙蝠尾翼,三叉戟)。
- 优点:
(1)客户端不必直到产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
(2)每一个具体建造者都相对独立,而与其他的建造者无关,因此可以很方便地替换或增加具体建造者。由于指挥者类对抽象建造者变成,增加新的具体建造者无需修改原有代码,系统扩展方便,符合开闭原则。
(3)可以更加精细地控制产品的创建过程。
- 缺点:
(1)建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间差异很大,例如组成部分都不相同,不适合使用建造者模式。
(2)产品的内部变化复杂,可能会导致需要定义很多的具体建造者类来实现这种变化,导致系统变得庞大。
- 适用环境:
(1)需要生成的产品对象有复杂的内部结构,通常对象会包含多个成员变量。
(2)需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
(3)对象的创建过程独立于创建该对象的类。
(4)隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。
- 与抽象工厂模式对比:
建造者返回一个完整的复杂产品,抽象工厂返回一系列相关的产品。在抽象工厂模式中,客户端通过选择具体工厂来生成所需对象,而在建造者模式中,客户端通过指定具体建造者的类型来指导Director类如何去生成一个对象,侧重于一步步构造一个复杂对象。如果将抽象工厂模式看成一个汽车配件生产厂,生产不同类型的汽车配件,那么建造者模式就是一个汽车组装厂,通过对配件进行组装返回一辆完整的汽车。