C++ 设计模式----“对象创建“模式

“对象创建”模式

 通过“对象创建” 模式绕开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
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;
}

C++ 设计模式----“对象创建“模式_第1张图片

FactoryMethod2.cpp

#include 
#include 

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)

C++ 设计模式----“对象创建“模式_第2张图片

要点总结

 Factory Method模式用于隔离类对象的使用者和具体类型之间的 耦合关系。面对一个经常变化的具体类型,紧耦合关系(new)会导 致软件的脆弱。

 Factory Method模式通过面向对象的手法,将所要创建的具体对 象工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系。

 Factory Method模式解决“单个对象”的需求变化。缺点在于要求创建方法/参数相同。

Abstract Factory 抽象工厂

**动机(Motivation)**:

在软件系统中,经常面临着**“一系列相互依赖的对象”**的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。

**问题思考(Consider)**:

如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?

EmployeeDAO1.cpp

#include
#include
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

将三个工厂合并为一个

C++ 设计模式----“对象创建“模式_第3张图片


//数据库访问有关的基类
//支持图像数据库(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
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;
}

C++ 设计模式----“对象创建“模式_第4张图片

AbstractFactory2.cpp

#include 
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;
}

C++ 设计模式----“对象创建“模式_第5张图片

模式定义

提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。

——《设计模式》GoF

结构(Structure)

C++ 设计模式----“对象创建“模式_第6张图片

要点总结

 如果没有应对**“多系列对象构建”**的需求变化,则没有必要使用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 
#include 

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 
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)

C++ 设计模式----“对象创建“模式_第7张图片

要点总结

 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 
#include 

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;
}

C++ 设计模式----“对象创建“模式_第8张图片

模式定义

将一个复杂对象的构建与其表示相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化)。

——《设计模式》GoF

结构(Structure)

C++ 设计模式----“对象创建“模式_第9张图片

要点总结

 Builder 模式主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。

 变化点在哪里,封装哪里—— Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。

 在Builder模式中,要注意不同语言中构造器内调用虚函数的差别(C++ vs. C#) 。

你可能感兴趣的:(c++,设计模式,开发语言)