zoukankan      html  css  js  c++  java
  • 设计模式 ProtoType 原型模式

    动机

    • 在软件系统中,经常面临着"某些结构复杂的对象"的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。
    • 如何应对这种变化?如何向"客户程序(使用这些对象的程序)"隔离出“这些易变对象”,从而使得依赖这些"易变对象"的客户程序不随着需求改变而改变。

    举个例子:

    找工作需要简历,以前没有打印机,都是手写很多份简历,且这些简历的内容都一样。但是如果要修改简历中的某项,所有写好的简历都的修改,工作量很大。有了打印设备之后。我们只需要手写一份,然后通过打印机复印多份即可。若要修改,只需修改原始版本,再去复印即可。原始的手写稿就相当与是一个原型,有了原型,就可以通过复印(拷贝)创造出更多的新简历。这就是原型模型的基本思想。

    定义

    • 使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。 ——《设计模式》GoF

     为什么要使用原型模式?

    我们使用原型模式是为了创建对象,在以下情况下可以考虑使用原型模式:

    • 当我们的对象类型不是一开始就确定的,而是在运行期间确定的话,那么通过利用这个对象克隆出一个新对象会更容易些。
    • 获取一个对象在某个状态下的副本
    • 处理一些较简单的对象时,且对象间的区别很小,可能就某些属性不同,就可以使用原型模式来创建新的对象。
    • 创建对象时,构造函数的参数很多,而自己不 清楚每个参数的意义,就可以使用原型模式创建对象,忽略创建的过程。

    由于克隆需要一个原型,而上面的类图中Prototype就这个原型,Prototype定义了克隆自身的Clone接口,由派生类进行实现,而实现原型模式的重点就在于这个Clone接口的实现。ConcretePrototype1类和ConcretePrototype2类继承自Prototype类,并实现Clone接口,实现克隆自身的操作;同时,在ConcretePrototype1类和ConcretePrototype2类中需要重写默认的复制构造函数,供Clone函数调用,Clone就是通过在内部调用重写的复制构造函数实现的。在后续的编码过程中,如果某个类需要实现Clone功能,就只需要继承Prototype类,然后重写自己的默认复制构造函数就好了。

    代码实现最简单的原型模式

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 //接口
     6 class Prototype {
     7    public:
     8     Prototype() {}
     9     virtual ~Prototype() {}
    10     virtual Prototype* clone() = 0;
    11 };
    12 
    13 //实现
    14 class ConcretePrototype : public Prototype {
    15    public:
    16     ConcretePrototype() : mCounter(0) {}
    17     virtual ~ConcretePrototype() {}
    18 
    19     //重写拷贝构造函数,以供clone函数调用
    20     ConcretePrototype(const ConcretePrototype& rhs) { mCounter = rhs.mCounter; }
    21 
    22     //复制自身
    23     virtual ConcretePrototype* clone() {
    24         //调用拷贝构造函数
    25         return new ConcretePrototype(*this);
    26     }
    27 
    28    private:
    29     int mCounter;
    30 };
    31 
    32 int main() {
    33     //生成对象
    34     ConcretePrototype* conProA = new ConcretePrototype();
    35 
    36     //复制自身
    37     ConcretePrototype* conProB = conProA->clone();
    38 
    39     delete conProA;
    40     conProA = nullptr;
    41     delete conProB;
    42     conProB = nullptr;
    43 
    44     return 0;
    45 }

    与其他创建型模式的比较

    工厂方法模式适用于生产较复杂,一个工厂生产单一的一种产品的时候;
    抽象工厂模式适用于一个工厂生产多个相互依赖的产品;
    建造者模式着重于复杂对象的一步一步创建,组装产品的过程,并在创建的过程中,可以控制每个简单对象的创建;
    原型模式则更强调的是从自身复制自己,创建要给和自己一模一样的对象。

    要点总结

    • 原型模式中具体的创建过程,是由对象本身提供,因此可以很方便的快速的构建新的对象。但是,原型模式的最大缺点是继承原型的子类都要实现Clone操作,这个是很困难的。例如,当所考虑的类已经存在时就难以新增Clone操作。当内部包括一些不支持拷贝或者有循环引用的对象时,实现克隆可能也会很困难。

    参考:C++设计模式——原型模式

  • 相关阅读:
    模拟两位选手进行n羽毛球比赛(15分赛制)并计算模拟胜率
    Pyton实例
    Python图片处理
    jieba库的使用和好玩的词云
    Python汉诺塔问题
    多线程同时操作一个epoll_fd
    Linux tr命令
    iptables 深入分析
    Linux xtables
    Linux IPC 共享内存
  • 原文地址:https://www.cnblogs.com/y4247464/p/14268033.html
Copyright © 2011-2022 走看看