在内蒙古这辽阔的草原上,放养着成千上万的奶牛。蒙牛集团在这里崛起,迅速抢占中国大半牛奶市场,造就了一个商业帝国。蒙牛集团牛奶生产流程大致是这样的: 放养奶牛--->牛奶加工--->牛奶包装--->销售。经历从放养奶牛到进行市场销售这一系列环节,蒙牛牛奶才得以诞生。虽然生产流程比这个流程还复杂,但对客户而言,根本不需要知道牛奶生产的细节,只需要到超市购买就行了。在设计模式中,也存在一个类似的模式,封装了产品创建的一系列操作过程,客户端无需知道这些操作流程就可以直接使用这个产品,称之为建造者模式。
1、建造者模式概述
建造者模式是较为复杂的创建型模式,它将客户端与包含多个组成部分(或部件)的复杂对象的创建过程分离,客户端无须知道复杂对象的内部组成部分与装配方式,只需要知道所需建造者的类型即可。它关注如何一步一步创建一个的复杂对象,不同的具体建造者定义了不同的创建过程,且具体建造者相互独立,增加新的建造者非常方便,无须修改已有代码,系统具有较好的扩展性。例如:用户不需要知道电脑的具体制造流程,而直接使用电脑就可以了,电脑具体制造流程对用户来说就相当于一个黑盒子。
建造者模式定义如下:
| 建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一种对象创建型模式。 |
建造者模式一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。

建造者模式结构图
在建造者模式结构图中包含如下几个角色:
Builder(抽象建造者):它为创建一个产品Product对象的各个部件指定抽象接口,在该接口中一般声明两类方法,一类方法是buildPartX(),它们用于创建复杂对象的各个部件;另一类方法是getResult(),它们用于返回复杂对象。Builder既可以是抽象类,也可以是接口。
ConcreteBuilder(具体建造者):它实现了Builder接口,实现各个部件的具体构造和装配方法,定义并明确它所创建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象。
Product(产品角色):它是被构建的复杂对象,包含多个组成部件,具体建造者创建该产品的内部表示并定义它的装配过程。
Director(指挥者):指挥者又称为导演类,它负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系,可以在其construct()建造方法中调用建造者对象的部件构造与装配方法,完成复杂对象的建造。客户端一般只需要与指挥者进行交互,在客户端确定具体建造者的类型,并实例化具体建造者对象,然后通过指挥者类的构造函数或者Setter方法将该对象传入指挥者类中。
在建造者模式的定义中提到了复杂对象,那么什么是复杂对象?简单来说,复杂对象是指那些包含多个成员属性的对象,这些成员属性也称为部件或零件,如汽车包括方向盘、发动机、轮胎等部件;电子邮件包括发件人、收件人、主题、内容、附件等部件;Socket数据包包含包头、包体、包尾等部件;XML配置文件包含头部信息、数据体、尾部信息等部件。
2、暴风影音播放器的设计与实现
现需要开发一款类似暴风影音的播放器,该播放软件提供多种界面显示模式,如完整模式、精简模式、记忆模式等。在不同的显示模式下主界面的组成元素有所差异,如在完整模式下将显示菜单、播放列表、主窗口、控制条等;在精简模式下只显示主窗口和控制条;而在记忆模式下将显示主窗口、控制条、收藏列表等。尝试使用建造者模式设计该软件。

暴风影音播放器是具体的产品,该产品包含菜单、主窗口、播放列表、播放进度条、收藏列表等部件。 暴风影音播放器.h头文件代码如下:
#ifndef _PLAYER_H_
#define _PLAYER_H_
#include
#include
using namespace std; //播放器 class Player { private: string m_strMenu; //菜单栏 string m_strWindow; //主窗口 string m_strPlayList; //播放列表 string m_strControlBar; //进度条 string m_strCollectList; //收藏列表 public: //设置部件 void SetMenu(string strMenu); void SetWindow(string strWindow); void SetPlayList(string strPlayList); void SetControlBar(string strControlBar); void SetCollectList(string strCollectList); //获取各部件 string GetMenu(); string GetWindow(); string GetPlayList(); string GetControlBar(); string GetCollectList(); //显示播放器窗口包含的部件 void Display(); }; #endif
暴风影响播放器Cpp文件代码如下:
#include "Player.h"
//设置主菜单部件
void Player::SetMenu(string strMenu)
{
m_strMenu = strMenu;
}
//设置主窗口部件
void Player::SetWindow(string strWindow)
{
m_strWindow = strWindow;
}
//设计播放列表部件
void Player::SetPlayList(string strPlayList)
{
m_strPlayList = strPlayList;
}
//设置滚动条部件
void Player::SetControlBar(string strControlBar)
{
m_strControlBar = strControlBar;
}
//设置收藏列表部件
void Player::SetCollectList(string strCollectList)
{
m_strCollectList = strCollectList;
}
//获取主菜单部件
string Player::GetMenu()
{
return m_strMenu;
}
//获取主窗口部件
string Player::GetWindow()
{
return m_strWindow;
}
//获取播放列表部件
string Player::GetPlayList()
{
return m_strPlayList;
}
//获取滚动条部件
string Player::GetControlBar()
{
return m_strControlBar;
}
//获取收藏列表部件
string Player::GetCollectList()
{
return m_strCollectList;
}
//显示播放器窗口包含的部件
void Player::Display()
{
cout << "---" << m_strWindow << endl;
cout << "---" << m_strMenu << endl;
cout << "---" << m_strPlayList << endl;
cout << "---" << m_strControlBar << endl;
cout << "---" << m_strCollectList << endl << endl;
} 暴风影音播放器能在完整模式、精简模式、记忆模式三种模式下播放,各播放模式下,暴风影音的部件不相同。