【设计模式】原型模式

1、 定义

1.1 标准定义

  原型模式( Prototype Pattern) 的简单程度仅次于单例模式和迭代器模式。 正是由于简单, 使用的场景才非常地多, 其定义如下:
  Specify the kinds of objects to create using a prototypical instance,and create new objects bycopying this prototype.( 用原型实例指定创建对象的种类, 并且通过拷贝这些原型创建新的对象。 )

1.2 通用类图

 

  Prototype模式提供了一个通过已存在对象进行新对象创建的接口(Clone), Clone()实现和具体的语言相关,在C++中通过拷贝构造函数实现。

2、 实现

2.1 类图

2.2 代码

2.2.1  原型类

// Prototype.h

#ifndef _PROTOTYPE_H_
#define _PROTOTYPE_H_

/*Prototype模式提供了一个通过已存在对象进行新对象创建的接口(Clone)
  Clone()实现和具体的语言相关,在C++中通过拷贝构造函数实现

作用:
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
*/
/*Prototype原型基类,定义Clone接口函数
*/

class Prototype
{
protected:

    Prototype();

public:

    virtual Prototype* Clone() const=0;//定义Clone接口,根据不同的派生类来实例化对象

    virtual ~Prototype();
};

//派生自Prototype,实现其接口函数
class ConcretePrototype1:public Prototype
{
public:

    ConcretePrototype1();//构造函数

    ~ConcretePrototype1();//析构函数

    ConcretePrototype1(const ConcretePrototype1&);//拷贝构造函数

    virtual Prototype* Clone() const;//实现基类定义的Clone接口,内部调用拷贝构造函数实现复制功能
};

//派生自Prototype,实现其接口函数
class ConcretePrototype2:public Prototype
{
public:

    ConcretePrototype2();//构造函数

    ~ConcretePrototype2();//析构函数

    ConcretePrototype2(const ConcretePrototype2&);//拷贝构造函数

    virtual Prototype* Clone() const;//实现基类定义的Clone接口,内部调用拷贝构造函数实现复制功能
};

#endif
// Prototype.cpp

#include "Prototype.h"
#include "iostream"

using namespace std;

////Prototype
Prototype::Prototype()
{
    cout<<"Prototype"<<endl;
}

Prototype::~Prototype()
{
    cout<<"~Prototype"<<endl;
}

//ConcretePrototype1
ConcretePrototype1::ConcretePrototype1()
{
    cout<<"ConcretePrototype1"<<endl;
}

ConcretePrototype1::~ConcretePrototype1()
{
    cout<<"~ConcretePrototype1"<<endl;
}

ConcretePrototype1::ConcretePrototype1(const ConcretePrototype1& cp)
{
    cout<<"ConcretePrototype1 copy"<<endl;
}

Prototype* ConcretePrototype1::Clone() const
{
    return new ConcretePrototype1(*this);
}

//ConcretePrototype2
ConcretePrototype2::ConcretePrototype2()
{
    cout<<"ConcretePrototype2"<<endl;
}

ConcretePrototype2::~ConcretePrototype2()
{
    cout<<"~ConcretePrototype2"<<endl;
}
 
ConcretePrototype2::ConcretePrototype2(const ConcretePrototype2& cp)
{
    cout<<"ConcretePrototype2 copy"<<endl;
}

Prototype* ConcretePrototype2::Clone() const
{
    return new ConcretePrototype2(*this);
}

2.2.2 调用

// main.cpp

#include "Prototype.h"
#include <iostream>

using namespace std;

int main()
{
    /*原型模式作用:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
      Prototype模式重在从自身复制自己创建新类,隐藏(不需知道)对象创建的细节
    */

    /*1、用原型实例p1指定创建对象的种类ConcretePrototype1 */
    Prototype* p1 = new ConcretePrototype1();
    /*2、通过拷贝这些原型创建新的对象 */
    Prototype* p2 = p1->Clone();

    cout<< "------------------------" << endl;

    Prototype* p3 = new ConcretePrototype2();
    Prototype* p4 = p3->Clone();

    cout<< "------------------------" << endl;

    delete p1;
    delete p2;

    cout<< "------------------------" << endl;

    delete p3;
    delete p4;

    return 0;
}

3、总结

3.1原型模式的优点

  ● 性能优良
  原型模式是在内存二进制流的拷贝, 要比直接new一个对象性能好很多, 特别是要在一个循环体内产生大量的对象时, 原型模式可以更好地体现其优点。

  ● 逃避构造函数的约束
  这既是它的优点也是缺点, 直接在内存中拷贝, 构造函数是不会执行的 。 优点就是减少了约束, 缺点也是减少了约束, 需要大家在实际应用时考虑。

3.2原型模式的使用场景

  ● 资源优化场景
  类初始化需要消化非常多的资源, 这个资源包括数据、 硬件资源等。

  ● 性能和安全要求的场景
  通过new产生一个对象需要非常繁琐的数据准备或访问权限, 则可以使用原型模式。

  ● 一个对象多个修改者的场景
  一个对象需要提供给其他对象访问, 而且各个调用者可能都需要修改其值时, 可以考虑使用原型模式拷贝多个对象供调用者使用。

3.3 几种构建模式区别

  Prototype模式和Builder模式、AbstractFactory模式都是通过一个类(对象实例)来专门负责对象的创建工作(工厂对象),它们之间的区别是:Builder模式重在复杂对象的一步步创建(并不直接返回对象),AbstractFactory模式重在产生多个相互依赖类的对象,而Prototype模式重在从自身复制自己创建新类。

posted @ 2017-07-26 22:03  Memset  阅读(257)  评论(0编辑  收藏  举报