前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式:原型模式

设计模式:原型模式

作者头像
王强
发布2020-09-24 15:36:20
5690
发布2020-09-24 15:36:20
举报
文章被收录于专栏:Python爬虫实战Python爬虫实战

系列文章回顾

┣ 设计模式:简单工厂模式

┣ 设计模式:工厂方法模式

┣ 设计模式:抽象工厂模式

┣ 设计模式:单例模式

┣ 设计模式:建造者模式

1 概述

原型模式使用原型实例指定创建对象的种类,并且通过拷贝原型对象创建新的对象。原型模式的关键点在于原型实例与实例的复制,实例的克隆分为深拷贝与浅拷贝。

  • 浅拷贝:对于字段是值类型的,则对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象与其副本引用同一对象。
  • 深拷贝:把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。

原型模式使用的是深拷贝, 使用原型模式复制对象不会调用类的构造方法。

2 图解

01_Prototype

原型模式包含三种角色:

  • Prototype(原型):定义用于复制现有实例来生成新实例的方法。
  • ConcretePrototype(具体原型):负责实现复制现有实例并生成新实例的方法。
  • Client(使用者):负责使用复制实例的方法生成新实例。

3 优缺点

优点:

  • 性能提高,直接拷贝内存里内容比直接新建实例节省资源;
  • 简化对象创建,避免了构造函数的约束,不受构造函数的限制直接复制对象;
  • 可通过深克隆的方式保存对象的状态,可以辅助实现撤销操作。

缺点:

  • 需要为每个类准备一个克隆方法,该方法位于类的内部,当对已有类进行改造时,需要修改原代码,违背了开闭原则;
  • 在实现深拷贝时需要写较复杂的代码,如果对象之间存在多重嵌套引用时,为了实现深拷贝,每一层对象对应的类必须支持深拷贝,实现比较麻烦。

4 应用场景

  • 资源优化场景:类初始化需要消耗非常多的资源,原型模式避免了此类消耗;
  • 性能和安全要求的场景:通过new产生一个对象需要非常繁琐的数据准备或访问权限时,可以使用原型模式;
  • 一个对象多个修改者的场景:一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以使用原型模式拷贝多个对象供调用者使用;
  • 系统要保存对象的状态,而对象的状态变化很小。

5 实例

02_Prototype_UML

5.1 Python 实现

  • prototype.py
代码语言:javascript
复制
#-*- coding: utf-8 -*-

'''
  原型模式
'''

from copy import copy, deepcopy

class Prototype(object):
    """原型类"""
    def __init__(self):
        super(Prototype, self).__init__()

    def clone(self):
        pass

class ConcretePrototype1(Prototype):
    """具体原型类"""
    def __init__(self):
        print("Create ConcretePrototype1")

    def clone(self):
        print("Copy ConcretePrototype1...")
        return deepcopy(self)

class ConcretePrototype2(Prototype):
    """具体原型类"""
    def __init__(self):
        print("Create ConcretePrototype2")

    def clone(self):
        print("Copy ConcretePrototype2...")
        return deepcopy(self)

if __name__ == '__main__':
    p1 = ConcretePrototype1()
    cp1 = p1.clone()

    p2 = ConcretePrototype2()
    cp2 = p2.clone()

输出结果:

代码语言:javascript
复制
Create ConcretePrototype1
Copy ConcretePrototype1...
Create ConcretePrototype2
Copy ConcretePrototype2...

5.2 C++ 实现

  • prototype.h
代码语言:javascript
复制
#ifndef PROTOTYPE_H
#define PROTOTYPE_H

#include <iostream>

using namespace std;

class Prototype
{
public:
    virtual ~Prototype() {}
    virtual Prototype* clone() const = 0;

protected:
    Prototype() {}
};

class ConcretePrototype1 : public Prototype
{
public:
    ConcretePrototype1() {
        cout << "Create ConcretePrototype1." << endl;
    }

    ConcretePrototype1(const ConcretePrototype1& other) {
        cout << "Copy ConcretePrototype1..." <<endl;
    }
    ~ConcretePrototype1() {}

    ConcretePrototype1* clone() const {
        return new ConcretePrototype1(*this);
    }
};

class ConcretePrototype2 : public Prototype
{
public:
    ConcretePrototype2() {
        cout << "Create ConcretePrototype2." << endl;
    }

    ConcretePrototype2(const ConcretePrototype2& other) {
        cout << "Copy ConcretePrototype2..." <<endl;
    }
    ~ConcretePrototype2() {}

    ConcretePrototype2* clone() const {
        return new ConcretePrototype2(*this);
    }
};

#endif // PROTOTYPE_H
  • main.cpp
代码语言:javascript
复制
#include <iostream>
#include "prototype.h"

using namespace std;

int main()
{
    Prototype* p1 = new ConcretePrototype1();
    Prototype* cp1 = p1->clone();

    Prototype* p2 = new ConcretePrototype2();
    Prototype* cp2 = p2->clone();

    delete p1;
    delete cp1;
    delete p2;
    delete cp2;

    return 0;
}

输出结果:

代码语言:javascript
复制
Create ConcretePrototype1.
Copy ConcretePrototype1...
Create ConcretePrototype2.
Copy ConcretePrototype2...

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-09-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 C与Python实战 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 概述
  • 2 图解
  • 3 优缺点
  • 4 应用场景
  • 5 实例
    • 5.1 Python 实现
      • 5.2 C++ 实现
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档