“对象创建”模式
通过“对象创建” 模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。
典型模式
• Factory Method
• Abstract Factory
• Prototype
• Builder
Factory Method工厂方法
**动机(Motivation)**💡:
在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。
**问题思考(Consider)**🤔:
如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种**“封装机制”来避免客户程序和这种“具体对象创建工作”**的紧耦合?
(一)依赖具体类
FileSplitter1.cpp
class ISplitter{
public:
virtual void split()=0;
virtual ~ISplitter(){}
};
class BinarySplitter : public ISplitter{
void split(){
// ...
}
};
class TxtSplitter: public ISplitter{
void split(){
// ...
}
};
class PictureSplitter: public ISplitter{
void split(){
// ...
}
};
class VideoSplitter: public ISplitter{
void split(){
// ...
}
};
MainForm1.cpp
#include"FileSplitter1.cpp"
class Form{
};
class TextBox;
class ProgressBar;
class ISplitter;
class MainForm : public Form
{
TextBox* txtFilePath;
TextBox* txtFileNumber;
ProgressBar* progressBar;
public:
void Button1_Click(){
ISplitter * splitter= new BinarySplitter();//依赖具体类
splitter->split();
}
};
(二)多态new
ISplitterFactory.cpp
//抽象类
class ISplitter{
public:
virtual void split()=0;
virtual ~ISplitter(){}
};
//工厂基类
class SplitterFactory{
public:
virtual ISplitter* CreateSplitter()=0;
virtual ~SplitterFactory(){}
};
FileSplitter2.cpp
#include"ISplitterFactory.cpp"
//具体类
class BinarySplitter : public ISplitter{
void split(){
// ...
}
};
class TxtSplitter: public ISplitter{
void split(){
// ...
}
};
class PictureSplitter: public ISplitter{
void split(){
// ...
}
};
class VideoSplitter: public ISplitter{
void split(){
// ...
}
};
//具体工厂
class BinarySplitterFactory: public SplitterFactory{
public:
virtual ISplitter* CreateSplitter(){
return new BinarySplitter();
}
};
class TxtSplitterFactory: public SplitterFactory{
public:
virtual ISplitter* CreateSplitter(){
return new TxtSplitter();
}
};
class PictureSplitterFactory: public SplitterFactory{
public:
virtual ISplitter* CreateSplitter(){
return new PictureSplitter();
}
};
class VideoSplitterFactory: public SplitterFactory{
public:
virtual ISplitter* CreateSplitter(){
return new VideoSplitter();
}
};
MainForm2.cpp
#include"ISplitterFactory.cpp"
class Form{
};
class TextBox;
class ProgressBar;
class MainForm : public Form
{
SplitterFactory* factory;//工厂
public:
MainForm(SplitterFactory* factory){
this->factory=factory;
}
void Button1_Click(){
ISplitter * splitter=factory->CreateSplitter(); //多态new
splitter->split();
}
};
FactoryMethod1.cpp
#include<iostream>
using namespace std;
class AbstractMonk {
public:
virtual void ability() = 0;//技能
virtual void petPhrase() = 0;//口头禅
virtual ~AbstractMonk() {}
};
//和尚--孙悟空
class SunWuKong : public AbstractMonk {
public:
void ability() {
cout << "腾云驾雾,七十二般变化,有极高的悟性" << endl;
}
void petPhrase() {
cout << "吃俺老孙一棒" << endl;
}
};
//和尚--猪八戒
class ZhuBaJie : public AbstractMonk {
public:
void ability() {
cout << "唱小曲,三十六般变化,吞吃人参果" << endl;
}
void petPhrase() {
cout << "猴哥!师父被妖怪抓走了!" << endl;
}
};
//和尚--沙僧
class ShaSen : public AbstractMonk {
public:
void ability() {
cout << "和事佬,辅助战斗" << endl;
}
void petPhrase() {
cout << "师傅放心,,大师兄会来救我们的" << endl;
}
};
//和尚--唐僧
class TangSen : public AbstractMonk {
public:
void ability() {
cout << "念经诵佛,让猴哥头疼" << endl;
}
void petPhrase() {
cout << "贫僧从东土大唐而来,前往西天拜佛求经" << endl;
}
};
class AbstractFactory {
public:
virtual AbstractMonk* createMonk() = 0;
virtual ~AbstractFactory() {}
};
class SunWuKongFactory : public AbstractFactory {
public:
AbstractMonk* createMonk() override{
return new SunWuKong();
}
~SunWuKongFactory() {
cout << "释放 SunWuKongFactory 类相关的内存资源" << endl;
}
};
class ZhuBaJieFactory : public AbstractFactory {
public:
AbstractMonk* createMonk() override {
return new ZhuBaJie();
}
~ZhuBaJieFactory() {
cout << "释放 ZhuBaJieFactory 类相关的内存资源" << endl;
}
};
class ShaSenFactory : public AbstractFactory {
public:
AbstractMonk* createMonk() override {
return new ShaSen();
}
~ShaSenFactory() {
cout << "释放 ShaSenFactory 类相关的内存资源" << endl;
}
};
class TangSenFactory : public AbstractFactory {
public:
AbstractMonk* createMonk() override {
return new TangSen();
}
~TangSenFactory() {
cout << "释放 TangSenFactory 类相关的内存资源" << endl;
}
};
/*
不论是和尚的基类,还是工厂类的基类,它们的虚函数可以是纯虚函数,
也可以是非纯虚函数。这样的基类在设计模式中就可以称之为抽象类
(此处的抽象类和 C++ 中对抽象类的定义有一点出入)。
*/
int main() {
//创建取经团队: 孙悟空 猪八戒 沙僧 唐僧
cout << "俺是齐天大圣,孙悟空" << endl;
AbstractFactory* swkFactory = new SunWuKongFactory;
AbstractMonk* swkObj = swkFactory->createMonk();
cout << "技能:";
swkObj->ability();
cout << "口头禅:";
swkObj->petPhrase();
cout << endl;
cout << "俺是天蓬元帅,猪八戒" << endl;
AbstractFactory* zbjFactory = new ZhuBaJieFactory;
AbstractMonk* zbjObj = zbjFactory->createMonk();
cout << "技能:";
zbjObj->ability();
cout << "口头禅:";
zbjObj->petPhrase();
cout << endl;
cout << "俺是卷帘大将,沙僧" << endl;
AbstractFactory* ssFactory = new ShaSenFactory;
AbstractMonk* ssObj = ssFactory->createMonk();
cout << "技能:";
ssObj->ability();
cout << "口头禅:";
ssObj->petPhrase();
cout << endl;
cout << "俺是金蝉子,法名玄奘,号三藏。" << endl;
AbstractFactory* tsFactory = new TangSenFactory;
AbstractMonk* tsObj = tsFactory->createMonk();
cout << "技能:";
tsObj->ability();
cout << "口头禅:";
tsObj->petPhrase();
cout << endl;
return 0;
}
FactoryMethod2.cpp
#include <iostream>
#include <string>
class Product
{
public:
virtual ~Product() {}
virtual std::string getName() = 0;
};
class ConcreteProductA : public Product
{
public:
~ConcreteProductA() {}
std::string getName()
{
return "type A";
}
};
class ConcreteProductB : public Product
{
public:
~ConcreteProductB() {}
std::string getName()
{
return "type B";
}
};
class Creator
{
public:
virtual ~Creator() {}
virtual Product* createProductA() = 0;
virtual Product* createProductB() = 0;
virtual void removeProduct(Product* product) = 0;
};
class ConcreteCreator : public Creator
{
public:
~ConcreteCreator() {}
Product* createProductA(){
return new ConcreteProductA();
}
Product* createProductB(){
return new ConcreteProductB();
}
void removeProduct(Product* product){
delete product;
}
};
int main()
{
Creator* creator = new ConcreteCreator();
Product* p1 = creator->createProductA();
std::cout << "Product: " << p1->getName() << std::endl;
creator->removeProduct(p1);
Product* p2 = creator->createProductB();
std::cout << "Product: " << p2->getName() << std::endl;
creator->removeProduct(p2);
delete creator;
return 0;
}
模式定义
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟(目的:解耦,手段:虚函数)到子类。
——《设计模式》GoF
结构(Structure)
要点总结
Factory Method模式用于隔离类对象的使用者和具体类型之间的 耦合关系。面对一个经常变化的具体类型,紧耦合关系(new)会导 致软件的脆弱。
Factory Method模式通过面向对象的手法,将所要创建的具体对 象工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系。
Factory Method模式解决“单个对象”的需求变化。缺点在于要求创建方法/参数相同。
Abstract Factory 抽象工厂
**动机(Motivation)**💡:
在软件系统中,经常面临着**“一系列相互依赖的对象”**的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。
**问题思考(Consider)**🤔:
如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?
EmployeeDAO1.cpp
#include<vector>
#include<string>
using std::string;
using std::vector;
class EmployeeDO{
};
class SqlConnection{
public:
string ConnectionString;
};
class SqlCommand{
public:
string CommandText;
SqlConnection* connection;
void SetConnection(SqlConnection* p){
this->connection = p;
}
SqlDataReader* ExecuteReader(){
// ...
return nullptr;
}
};
class SqlDataReader{
public:
bool Read(){
// ...
return true;
}
};
class EmployeeDAO{
public:
vector<EmployeeDO> GetEmployees(){
SqlConnection* connection = new SqlConnection();
connection->ConnectionString = "...";
SqlCommand* command = new SqlCommand();
command->CommandText="...";
command->SetConnection(connection);
SqlDataReader* reader = command->ExecuteReader();
while (reader->Read()){
// ...
}
}
};
EmployeeDAO2.cpp
**缺点:这三个必须是同系列的,有关联性
无法实现不同工厂生产出来的是不同组的东西,无法搭配到一起
即只能实现sql系列和oracle系列,无法实现sql和oracle的混合搭配系列
//数据库访问有关的基类
//支持图像数据库(IDB)
class IDBConnection{
};
class IDBConnectionFactory{
public:
virtual IDBConnection* CreateDBConnection()=0;
};
class IDBCommand{
};
class IDBCommandFactory{
public:
virtual IDBCommand* CreateDBCommand()=0;
};
class IDataReader{
};
class IDataReaderFactory{
public:
virtual IDataReader* CreateDataReader()=0;
};
//支持SQL Server
class SqlConnection: public IDBConnection{
};
class SqlConnectionFactory:public IDBConnectionFactory{
};
class SqlCommand: public IDBCommand{
};
class SqlCommandFactory:public IDBCommandFactory{
};
class SqlDataReader: public IDataReader{
};
class SqlDataReaderFactory:public IDataReaderFactory{
};
//支持Oracle
class OracleConnection: public IDBConnection{
};
class OracleConnectionFactory :public IDBConnectionFactory {
};
class OracleCommand: public IDBCommand{
};
class OracleCommandFactory :public IDBCommandFactory {
};
class OracleDataReader: public IDataReader{
};
class OracleDataReaderFactory :public IDataReaderFactory {
};
class EmployeeDAO{
/*
缺点:这三个必须是同系列的,有关联性
无法实现不同工厂生产出来的是不同组的东西,无法搭配到一起
即只能实现sql系列和oracle系列,无法实现sql和oracle的混合搭配系列
*/
IDBConnectionFactory* dbConnectionFactory;
IDBCommandFactory* dbCommandFactory;
IDataReaderFactory* dataReaderFactory;
public:
vector<EmployeeDO> GetEmployees(){
IDBConnection* connection =
dbConnectionFactory->CreateDBConnection();
connection->ConnectionString("...");
IDBCommand* command =
dbCommandFactory->CreateDBCommand();
command->CommandText("...");
command->SetConnection(connection); //关联性
IDBDataReader* reader = command->ExecuteReader(); //关联性
while (reader->Read()){
}
}
};
EmployeeDAO3.cpp
将三个工厂合并为一个
//数据库访问有关的基类
//支持图像数据库(IDB)
class IDBConnection{
};
class IDBCommand{
};
class IDataReader{
};
class IDBFactory{
public:
virtual IDBConnection* CreateDBConnection()=0;
virtual IDBCommand* CreateDBCommand()=0;
virtual IDataReader* CreateDataReader()=0;
};
//支持SQL Server
class SqlConnection: public IDBConnection{
};
class SqlCommand: public IDBCommand{
};
class SqlDataReader: public IDataReader{
};
class SqlDBFactory:public IDBFactory{
public:
virtual IDBConnection* CreateDBConnection()=0;
virtual IDBCommand* CreateDBCommand()=0;
virtual IDataReader* CreateDataReader()=0;
};
//支持Oracle
class OracleConnection: public IDBConnection{
};
class OracleCommand: public IDBCommand{
};
class OracleDataReader: public IDataReader{
};
class EmployeeDAO{
IDBFactory* dbFactory;
public:
vector<EmployeeDO> GetEmployees(){
IDBConnection* connection =
dbFactory->CreateDBConnection();
connection->ConnectionString("...");
IDBCommand* command =
dbFactory->CreateDBCommand();
command->CommandText("...");
command->SetConnection(connection); //关联性
IDBDataReader* reader = command->ExecuteReader(); //关联性
while (reader->Read()){
}
}
};
AbstractFactory1.cpp
#include<iostream>
using namespace std;
//船体
class ShipBody {
public:
virtual string getShipBody() = 0;
virtual ~ShipBody() {};
};
//木材船体
class WoodBody : public ShipBody {
public:
string getShipBody() override {
return string("用<木材>制作轮船船体...");
}
};
//钢铁船体
class IronBody : public ShipBody {
public:
string getShipBody() override {
return string("用<钢铁>制作轮船船体...");
}
};
//金属船体
class MetalBody : public ShipBody {
public:
string getShipBody() override {
return string("用<合金>制作轮船船体...");
}
};
//动力
class Engine {
public:
virtual string getEngine() = 0;
virtual ~Engine() {}
};
class Human :public Engine {
public:
string getEngine() override{
return string("使用<人力驱动>");
}
};
class Diesel :public Engine {
public:
string getEngine() override {
return string("使用<内燃机驱动>");
}
};
class Nuclear :public Engine {
public:
string getEngine() override {
return string("使用<核能驱动>");
}
};
//武器
class Weapon {
public:
virtual string getWeapon() = 0;
virtual ~Weapon() {};
};
class Gun :public Weapon {
public:
string getWeapon() override {
return string("配备的武器是<枪>");
}
};
class Cannon :public Weapon {
public:
string getWeapon() override {
return string("配备的武器是<自动机关炮>");
}
};
class Laser : public Weapon
{
public:
string getWeapon() override
{
return string("配备的武器是<激光>");
}
};
//轮船类
class Ship {
public:
Ship(ShipBody* body, Weapon* weapon, Engine* engine) :
m_body(body), m_weapon(weapon), m_engine(engine) {}
string getProperty() {
string info = m_body->getShipBody() + m_weapon->getWeapon() + m_engine->getEngine();
return info;
}
~Ship(){
delete m_body;
delete m_weapon;
delete m_engine;
}
private:
ShipBody* m_body = nullptr;
Weapon* m_weapon = nullptr;
Engine* m_engine = nullptr;
};
//工厂类
class AbstractFactory {
public:
virtual Ship* createShip() = 0;
virtual ~AbstractFactory() {}
};
class BasicFactory :public AbstractFactory {
public:
Ship* createShip() override {
Ship* ship = new Ship(new WoodBody, new Gun, new Human);
cout << "<基础型>战船生产完毕, 可以下水啦..." << endl;
return ship;
}
};
class StandardFactory : public AbstractFactory {
public:
Ship* createShip() override {
Ship* ship = new Ship(new IronBody, new Cannon, new Diesel);
cout << "<标准型>战船生产完毕, 可以下水啦..." << endl;
return ship;
}
};
class UltimateFactory : public AbstractFactory {
public:
Ship* createShip() override {
Ship* ship = new Ship(new MetalBody, new Laser, new Nuclear);
cout << "<旗舰型>战船生产完毕, 可以下水啦..." << endl;
return ship;
}
};
int main() {
AbstractFactory* basicFactory = new BasicFactory();
Ship* basicShip = basicFactory->createShip();
cout << basicShip->getProperty() << endl;
delete basicShip;
delete basicFactory;
AbstractFactory* standardFactory = new StandardFactory();
Ship* standardShip = standardFactory->createShip();
cout << standardShip->getProperty() << endl;
delete standardShip;
delete standardFactory;
AbstractFactory* ultimateFactory = new UltimateFactory();
Ship* ultimateShip = ultimateFactory->createShip();
cout << ultimateShip->getProperty() << endl;
delete ultimateShip;
delete ultimateFactory;
return 0;
}
AbstractFactory2.cpp
#include <iostream>
using namespace std;
class AbstractProductA
{
public:
virtual ~AbstractProductA() {}
virtual const char* getName() = 0;
};
class ProductA1 : public AbstractProductA
{
public:
~ProductA1() {}
const char* getName()
{
return "A1";
}
};
class ProductA2 : public AbstractProductA
{
public:
~ProductA2() {}
const char* getName()
{
return "A2";
}
};
class AbstractProductB
{
public:
virtual ~AbstractProductB() {}
virtual const char* getName() = 0;
};
class ProductB1 : public AbstractProductB
{
public:
~ProductB1() {}
const char* getName()
{
return "B1";
}
};
class ProductB2 : public AbstractProductB
{
public:
~ProductB2() {}
const char* getName()
{
return "B2";
}
};
class AbstractFactory
{
public:
virtual ~AbstractFactory() {}
virtual AbstractProductA *CreateProductA() = 0;
virtual AbstractProductB *CreateProductB() = 0;
};
class ConcreteFactory1 : public AbstractFactory
{
public:
~ConcreteFactory1() {}
AbstractProductA* CreateProductA()
{
return new ProductA1();
}
AbstractProductB* CreateProductB()
{
return new ProductB1();
}
};
class ConcreteFactory2 : public AbstractFactory
{
public:
~ConcreteFactory2() {}
AbstractProductA *CreateProductA()
{
return new ProductA2();
}
AbstractProductB *CreateProductB()
{
return new ProductB2();
}
};
int main()
{
ConcreteFactory1 *factory1 = new ConcreteFactory1();
ConcreteFactory2 *factory2 = new ConcreteFactory2();
cout << "-------------ConcreteFactory1(CreateProductA,CreateProductB)-------------" << endl;
AbstractProductA *p11 = factory1->CreateProductA();
std::cout << "Product: " << p11->getName() << std::endl;
AbstractProductB* p12 = factory1->CreateProductB();
std::cout << "Product: " << p12->getName() << std::endl;
cout << "-------------ConcreteFactory2(CreateProductA,CreateProductB)-------------" << endl;
AbstractProductA *p21 = factory2->CreateProductA();
std::cout << "Product: " << p21->getName() << std::endl;
AbstractProductB* p22 = factory2->CreateProductB();
std::cout << "Product: " << p22->getName() << std::endl;
delete p11;
delete p12;
delete p21;
delete p22;
delete factory1;
delete factory2;
return 0;
}
模式定义
提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。
——《设计模式》GoF
结构(Structure)
要点总结
如果没有应对**“多系列对象构建”**的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的工厂完全可以。
“系列对象”指的是在某一特定系列下的对象之间有相互依赖、或作用的关系。不同系列的对象之间不能相互依赖。
Abstract Factory模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变动。
Prototype原型模式
**动机(Motivation)**💡:
在软件系统中,经常面临着**“某些结构复杂的对象”**的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。
**问题思考(Consider)**🤔:
如何应对这种变化? 如何向**“客户程序(使用这些对象的程序)”隔离出“这些易变对象”,从而使得“依赖这些易变对象的客户程序”**不随着需求改变而改变?
C++执行代码:
Prototype.cpp
//抽象类
class ISplitter{
public:
virtual void split()=0;
virtual ISplitter* clone()=0; //通过克隆自己来创建对象
virtual ~ISplitter(){}
};
ConCretePrototype.cpp
#include"Prototype.cpp"
//具体类
class BinarySplitter : public ISplitter{
public:
virtual void split(){}
virtual ISplitter* clone(){
return new BinarySplitter(*this);
}
};
class TxtSplitter: public ISplitter{
public:
virtual void split(){}
virtual ISplitter* clone(){
return new TxtSplitter(*this);
}
};
class PictureSplitter: public ISplitter{
public:
virtual void split(){}
virtual ISplitter* clone(){
return new PictureSplitter(*this);
}
};
class VideoSplitter: public ISplitter{
public:
virtual void split(){}
virtual ISplitter* clone(){
return new VideoSplitter(*this);
}
};
Client.cpp (原型对象只供克隆,不能使用)
#include"Prototype.cpp"
class Form{
};
class MainForm : public Form
{
ISplitter* prototype;//原型对象
public:
MainForm(ISplitter* prototype){
this->prototype=prototype;
}
void Button1_Click(){
ISplitter * splitter=
prototype->clone(); //克隆原型
splitter->split();
}
};
网上代码(来自这个博主):https://github.com/chouxianyu/design-patterns-cpp
Prototype.cpp
#include <iostream>
#include <string>
class Prototype
{
public:
virtual ~Prototype() {}
virtual Prototype* clone() = 0;
virtual std::string type() = 0;
};
class ConcretePrototypeA : public Prototype
{
public:
~ConcretePrototypeA() {}
Prototype* clone()
{
return new ConcretePrototypeA();
}
std::string type()
{
return "type A";
}
};
class ConcretePrototypeB : public Prototype
{
public:
~ConcretePrototypeB() {}
Prototype* clone()
{
return new ConcretePrototypeB();
}
std::string type()
{
return "type B";
}
};
class Client
{
public:
static void init()
{
types[ 0 ] = new ConcretePrototypeA();
types[ 1 ] = new ConcretePrototypeB();
}
static void remove()
{
delete types[ 0 ];
delete types[ 1 ];
}
static Prototype* make( const int index )
{
if ( index >= n_types )
{
return nullptr;
}
return types[ index ]->clone();
}
private:
static Prototype* types[ 2 ];
static int n_types;
};
Prototype* Client::types[ 2 ];
int Client::n_types = 2;
int main()
{
Client::init();
Prototype *prototype1 = Client::make( 0 );
std::cout << "Prototype: " << prototype1->type() << std::endl;
delete prototype1;
Prototype *prototype2 = Client::make( 1 );
std::cout << "Prototype: " << prototype2->type() << std::endl;
delete prototype2;
Client::remove();
return 0;
}
RobotPrototype.cpp
#include <iostream>
using namespace std;
class Robot {
public:
virtual Robot* clone() = 0;
virtual string selfIntroduction() = 0;
virtual ~Robot() {}
};
class Robot10086 : public Robot {
public:
Robot* clone() override{
return new Robot10086(*this);
}
string selfIntroduction()override {
return string("我是机器人10086,可以为您提供话费咨询服务!!!");
}
};
class Robot10087 : public Robot {
public:
Robot* clone() override{
return new Robot10087(*this);
}
string selfIntroduction() override {
return string("我是机器人10087,可以为您提供流量查询服务!!!");
}
};
int main()
{
Robot* obj = new Robot10086;
Robot* robot = obj->clone();
cout << robot->selfIntroduction() << endl;
delete robot;
delete obj;
Robot* obj1 = new Robot10087;
Robot* robot1 = obj1->clone();
cout << robot1->selfIntroduction() << endl;
delete robot1;
delete obj1;
return 0;
}
模式定义
使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。
——《设计模式》 GoF
结构(Structure)
要点总结
Prototype模式同样用于隔离类对象的使用者和具体类型 (易变类)之间的耦合关系,它同样要求这些**“易变类”拥有“稳定的接口”**。
Prototype模式对于**“如何创建易变类的实体对象”采用“原型克隆”的方法来做,它使得我们可以非常灵活地动态创建“拥有某些稳定接口”**的新对象一-所需工作仅仅是注册一个新类的对象 (即原型)然后在任何需要的地方Clone。
Prototype模式中的Clone方法可以利用某些框架中的序列化来实现深拷贝。
Builder 构建器
**动机(Motivation)**💡:
在软件系统中,有时候面临着**“一个复杂对象”**的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
**问题思考(Consider)**🤔:
如何应对这种变化?如何提供一种**“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”**不随着需求改变而改变?
C++执行代码:
builder.cpp
class House{
//....
};
class HouseBuilder {
public:
House* pHouse;
House* GetResult(){
return pHouse;
}
virtual ~HouseBuilder(){}
virtual void BuildPart1()=0;
virtual void BuildPart2()=0;
virtual bool BuildPart3()=0;
virtual void BuildPart4()=0;
virtual void BuildPart5()=0;
};
class StoneHouse: public House{
};
class StoneHouseBuilder: public HouseBuilder{
public:
virtual void BuildPart1(){
//pHouse->Part1 = ...;
}
virtual void BuildPart2(){
}
virtual bool BuildPart3(){
}
virtual void BuildPart4(){
}
virtual void BuildPart5(){
}
};
class HouseDirector{
public:
HouseBuilder* pHouseBuilder;
HouseDirector(HouseBuilder* pHouseBuilder){
this->pHouseBuilder=pHouseBuilder;
}
House* Construct(){
pHouseBuilder->BuildPart1();
for (int i = 0; i < 4; i++){
pHouseBuilder->BuildPart2();
}
bool flag=pHouseBuilder->BuildPart3();
if(flag){
pHouseBuilder->BuildPart4();
}
pHouseBuilder->BuildPart5();
return pHouseBuilder->GetResult();
}
};
Builder.cpp
#include <iostream>
#include <string>
class Product
{
public:
void makeA( const std::string &part )
{
partA = part;
}
void makeB( const std::string &part )
{
partB = part;
}
void makeC( const std::string &part )
{
partC = part;
}
std::string get()
{
return (partA + " " + partB + " " + partC);
}
private:
std::string partA;
std::string partB;
std::string partC;
};
class Builder
{
public:
virtual ~Builder() {}
Product get()
{
return product;
}
virtual void buildPartA() = 0;
virtual void buildPartB() = 0;
virtual void buildPartC() = 0;
protected:
Product product;
};
class ConcreteBuilderX : public Builder
{
public:
void buildPartA()
{
product.makeA( "A-X" );
}
void buildPartB()
{
product.makeB( "B-X" );
}
void buildPartC()
{
product.makeC( "C-X" );
}
};
class ConcreteBuilderY : public Builder
{
public:
void buildPartA()
{
product.makeA( "A-Y" );
}
void buildPartB()
{
product.makeB( "B-Y" );
}
void buildPartC()
{
product.makeC( "C-Y" );
}
};
class Director {
public:
Director() : builder() {}
~Director()
{
if ( builder )
{
delete builder;
}
}
void set( Builder *b )
{
if ( builder )
{
delete builder;
}
builder = b;
}
Product get()
{
return builder->get();
}
void construct()
{
builder->buildPartA();
builder->buildPartB();
builder->buildPartC();
}
private:
Builder *builder;
};
int main()
{
Director director;
director.set( new ConcreteBuilderX );
director.construct();
Product product1 = director.get();
std::cout << "1st product parts: " << product1.get() << std::endl;
director.set( new ConcreteBuilderY );
director.construct();
Product product2 = director.get();
std::cout << "2nd product parts: " << product2.get() << std::endl;
return 0;
}
模式定义
将一个复杂对象的构建与其表示相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化)。
——《设计模式》GoF
结构(Structure)
要点总结
Builder 模式主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
变化点在哪里,封装哪里—— Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。
在Builder模式中,要注意不同语言中构造器内调用虚函数的差别(C++ vs. C#) 。