C++实现Creational - Prototype模式

抽象不能依赖于实现细节,实现细节应该依赖于抽象。

 

在软件系统中,经常面临着某些结构复杂的对象的创建工作,由于需求的变化,这些对象经常面临着剧烈的变化,但是他们却拥有比较稳定一致的接口。Prototype设计模式,就是为了解决如何向客户程序隔离出这些易变对象,从而使得依赖这些易变对象的客户程序不随着需求的改变而改变。

 

Prototype设计模式指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。

 

要点:

-          Prototype设计模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些易变类拥有稳定的接口

-          Prototype设计模式对于如何创建易变类的实体对象采用原型克隆的方法来做,它使得我们可以非常灵活地动态创建拥有某些稳定接口的新对象,所需要的工作仅仅是注册一个新类的对象(即原型),然后在需要的地方不断地Clone

-          Clone时要注意使用Deep Clone

-        Java中可以考虑使用序列化或者直接new一个新的子对象的方式来实现Deep Clone

         -        C++中一般采用直接new一个新的子对象的方法来实现Deep Clone

         -        C#中一般采用MemberwiseClone()方法、序列化方法或者直接用new一个新的子对象的方法来实现Deep Clone

 

Prototype模式最主要的两个值得注意的地方:

1. Clone的方式创建对象

2. 一个对象需要多个副本以进行不同的处理。For example, let’s consider the case in which you need to make a number of queries to an extensive database to construct an answer. Once you have this answer as a table or ResultSet, you might want to manipulate it to produce other answers without your having to issue additional queries. (下面的实现代码,即以此为例)

 

Prototype模式之UML类图:

 

C++实现Prototype模式的具体示例代码:

// Prototype.h

#include <iostream>

#include <vector>

#include <memory>

#include <string>

using namespace std;

 

// 跳水运动员,模拟数据库的一条记录

class Diver

{

private:

         int id;                            // 跳水运动员的id

         string name;              // 跳水运动员的姓名

         double score;            // 跳水运动员的分数

public:

         void set_id(const int& id)

         {

                   this->id = id;

         }

 

         int get_id() const

         {

                   return id;

         }

 

         void set_name(const string& name)

         {

                   this->name = name;

         }

 

         string get_name() const

         {

                   return name;

         }

 

         void set_score(const double& score)

         {

                   this->score = score;

         }

 

         double get_score() const

         {

                   return score;

         }

 

public:

         ~Diver()

         {

                   cout << "in destructor of Diver..." << endl;

         }

};

 

// 抽象类,模拟从数据库读取的一个结果集,相当于UML类图中的Prototype

class ResultSet

{

protected:

         vector<Diver> divers;

 

public:

         virtual auto_ptr<ResultSet> clone() = 0;

         virtual vector<Diver> get_divers() = 0;

         virtual bool sort(const string& by_what_rule) = 0;

 

         virtual ~ResultSet()

         {

                   cout << "in the destructor of ResultSet..." << endl;

         }

};

 

// 相当于UML类图中的ConcreatePrototype1

class DiversResultSet : public ResultSet

{

public:

         DiversResultSet()              // 模拟一个结果集

         {

                   Diver d1, d2, d3;

 

                   d1.set_id(1);

                   d1.set_name("Jack Jones");

                   d1.set_score(634.28);

                   divers.push_back(d1);

 

                   d2.set_id(2);

                   d2.set_name("Nick Xiong");

                   d2.set_score(686.98);

                   divers.push_back(d2);

 

                   d3.set_id(3);

                   d3.set_name("Frank Bryant");

                   d3.set_score(636.68);

                   divers.push_back(d3);

         }

 

         vector<Diver> get_divers()

         {

                   return divers;

         }

 

         auto_ptr<ResultSet> clone()            // 这个函数整个Prototype模式中的关键

         {

                   auto_ptr<ResultSet> divers_result_set(new DiversResultSet());

                   return divers_result_set;

         }

 

         bool sort(const string& by_what_rule)

         {

                   if((by_what_rule.compare("score") != 0) && (by_what_rule.compare("name") != 0))

                   {

                            return false;

                   }

                   else if(by_what_rule.compare("score") == 0)    // 下面代码模拟按照分数排序

                   {

                            Diver d1 = divers[0];

                            Diver d2 = divers[1];

                            Diver d3 = divers[2];

 

                            divers.resize(0);

                            divers.push_back(d2);

                            divers.push_back(d3);

                            divers.push_back(d1);

                   }

                   else // 下面代码模拟按照姓名排序

                   {

                            Diver d1 = divers[0];

                            Diver d2 = divers[1];

                            Diver d3 = divers[2];

 

                            divers.resize(0);

                            divers.push_back(d3);

                            divers.push_back(d1);

                            divers.push_back(d2);

                   }

                   return true;

         }

 

public:

         ~DiversResultSet()

         {

                   cout << "in the destructor of DiversResultSet..." << endl;

         }

};

 

// 测试代码:

// Prototype.cpp

#include "Prototype.h"

 

int main(int agrc, char **argv)

{

         auto_ptr<ResultSet> rs(new DiversResultSet);

         vector<Diver> vd1 = rs->get_divers();

         auto_ptr<ResultSet> rs1(rs->clone());                // 克隆一次

         auto_ptr<ResultSet> rs2(rs->clone());                // 再克隆一次

 

         for(vector<Diver>::const_iterator cit = vd1.begin(); cit != vd1.end(); cit++)

         {

                   cout << cit->get_id() << " " << cit->get_name() << "\t\t" << cit->get_score() << endl;

         }

 

        

         rs1->sort("score");

         vector<Diver> vd2 = rs1->get_divers();

         for(vector<Diver>::const_iterator cit = vd2.begin(); cit != vd2.end(); cit++)

         {

                   cout << cit->get_id() << " " << cit->get_name() << "\t\t" << cit->get_score() << endl;

         }

 

         rs2->sort("name");

         vector<Diver> vd3 = rs2->get_divers();

         for(vector<Diver>::const_iterator cit = vd3.begin(); cit != vd3.end(); cit++)

         {

                   cout << cit->get_id() << " " << cit->get_name() << "\t\t" << cit->get_score() << endl;

         }

}

 

上述程序的输出结果大致如下:

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

1 Jack Jones             634.28

2 Nick Xiong               686.98

3 Frank Bryant           636.68

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

2 Nick Xiong               686.98

3 Frank Bryant           636.68

1 Jack Jones             634.28

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

3 Frank Bryant           636.68

1 Jack Jones             634.28

2 Nick Xiong               686.98

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in the destructor of DiversResultSet...

in the destructor of ResultSet...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in the destructor of DiversResultSet...

in the destructor of ResultSet...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

in the destructor of DiversResultSet...

in the destructor of ResultSet...

in destructor of Diver...

in destructor of Diver...

in destructor of Diver...

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值