《设计模式的艺术》笔记 - 原型模式

这篇具有很好参考价值的文章主要介绍了《设计模式的艺术》笔记 - 原型模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

介绍

        使用原型实例指定创建对象的种类,并且通过克隆这些原型创建新的对象。原型模式是一种对象创建型模式。

实现

myclass.h

//
// Created by yuwp on 2024/1/12.
//

#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H

#include <iostream>

class Prototype {
public:
    void setId(uint64_t id);

    uint64_t getId();

    virtual Prototype *clone() = 0;

private:
    uint64_t m_id;
};

class ConcretePrototype : public Prototype {
public:
    Prototype *clone() override;
};

#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//

#include "myclass.h"

void Prototype::setId(uint64_t id) {
    m_id = id;
}

uint64_t Prototype::getId() {
    return m_id;
}

Prototype* ConcretePrototype::clone() {
    ConcretePrototype *prototype = new ConcretePrototype();
    prototype->setId(this->getId());
    return prototype;
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"

int main() {
    Prototype *obj1 = new ConcretePrototype();
    std::cout << "obj1: " << std::hex << obj1 << ", id: " << obj1->getId() << std::endl;
    auto obj2 = obj1->clone();
    std::cout << "obj2: " << std::hex << obj2 << ", id: " << obj2->getId() << std::endl;
    delete obj1;
    delete obj2;

    return 0;
}

总结

        优点:

        1. 当创建新的对象实例较为复杂时,使用原型模式可以简化对象的创建过程,通过复制一个已有实例可以提高新实例的创建效率。

        2. 扩展性较好。由于在原型模式中提供了抽象原型类,在客户端可以针对抽象原型类进行编程,而将具体原型类写在配置文件中,增加或减少具体原型类对原有系统都没有任何影响。

        3. 原型模式提供了简化的创建结构。工厂方法模式常常需要有一个与产品类等级结构相同的工厂等级结构,而原型模式就不需要这样。原型模式中产品的复制是通过封装在原型类中的克隆方法实现的,无须专门的工厂类来创建产品。

        4. 可以使用深克隆的方式保存对象的状态。使用原型模式将对象复制一份并将其状态保存起来,以便在需要的时候使用,例如恢复到某一历史状态,可辅助实现撤销操作。

        缺点:

        1. 需要为每一个类配备一个克隆方法,而且该克隆方法位于一个类的内部。当对已有的类进行改造时,需要修改源代码,违背了开闭原则。

        2. 在实现深克隆时需要编写较为复杂的代码,而且当对象之间存在多重的嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来可能会比较麻烦。

        适用场景:

        1. 创建新对象成本较大(例如初始化需要占用较长的时间,占用太多的CPU资源或网络资源)。新的对象可以通过原型模式对已有对象进行复制来获得,如果是相似对象,则可以对其成员变量稍作修改。

        2. 如果系统要保存对象的状态,而对象的状态变化很小,或者对象本身占用内存较少时,可以使用原型模式配合备忘录模式(本书第21章介绍)来实现。

        3. 需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少的几个组合状态。通过复制原型对象得到新实例可能比使用构造函数创建一个新实例更加方便。

练习

myclass.h

//
// Created by yuwp on 2024/1/12.
//

#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H

#include <iostream>

class Address {
public:
    std::string m_name;
    uint32_t m_id;
};

class Object {
public:
    virtual Object *deepClone() = 0;
    virtual Object *clone() = 0;
};

class Customer : public Object {
public:
    Customer() {}
    Customer(Address *addr);
    Address *getAddress();
    void setAddress(Address *addr);
    Object *deepClone() override;
    Object *clone() override;

private:
    Address *m_addr;
};

#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//

#include "myclass.h"

Customer::Customer(Address *addr) {
    m_addr = addr;
}

Address* Customer::getAddress() {
    return m_addr;
}

void Customer::setAddress(Address *addr) {
    m_addr = addr;
}

Object* Customer::clone() {
    Customer *customer = new Customer();
    customer->setAddress(m_addr);
    return customer;
}

Object* Customer::deepClone() {
    Customer *customer = new Customer();
    Address *address = new Address();
    address->m_id = m_addr->m_id;
    address->m_name = m_addr->m_name;
    customer->setAddress(address);
    return customer;
}

main.cpp文章来源地址https://www.toymoban.com/news/detail-804815.html

#include <iostream>
#include <mutex>
#include "myclass.h"

int main() {
    Address *addr = new Address();
    addr->m_id = 1;
    addr->m_name = "abc";
    Object *obj1 = new Customer(addr);
    auto obj2 = obj1->clone();
    auto obj3 = obj1->deepClone();
    std::cout << "obj1: " << std::hex << obj1 << ", addr = " << std::hex << dynamic_cast<Customer *>(obj1)->getAddress() << ", id = " << dynamic_cast<Customer *>(obj1)->getAddress()->m_id << ", name = " << dynamic_cast<Customer *>(obj1)->getAddress()->m_name << std::endl;
    std::cout << "obj2: " << std::hex << obj2 << ", addr = " << std::hex << dynamic_cast<Customer *>(obj2)->getAddress() << ", id = " << dynamic_cast<Customer *>(obj2)->getAddress()->m_id << ", name = " << dynamic_cast<Customer *>(obj2)->getAddress()->m_name << std::endl;
    std::cout << "obj3: " << std::hex << obj3 << ", addr = " << std::hex << dynamic_cast<Customer *>(obj3)->getAddress() << ", id = " << dynamic_cast<Customer *>(obj3)->getAddress()->m_id << ", name = " << dynamic_cast<Customer *>(obj3)->getAddress()->m_name << std::endl;

    return 0;
}

到了这里,关于《设计模式的艺术》笔记 - 原型模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《设计模式的艺术》笔记 - 状态模式

            状态模式允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。其别名为状态对象,状态模式是一种对象行为模式。 myclass.h myclass.cpp main.cpp         1. 封装了状态的转换规则。在状态模式中可以将状态的转换代码封装在环境类或者具体状

    2024年01月25日
    浏览(61)
  • 《设计模式的艺术》笔记 - 命令模式

            命令模式将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。命令模式是一种对象行为模式,其别名为动作模式或事务模式。 myclass.h myclass.cpp main.cpp         只需要增加一个CommandQueue类即可

    2024年01月20日
    浏览(56)
  • 《设计模式的艺术》笔记 - 外观模式

            外观模式中外部与一个子系统的通信通过一个统一的外观角色进行,为子系统中的一组接口提供一个一致的入口。外观模式定义了一个高层接口,这个接口使得子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。 myclass.h myclass.cpp main.cpp    

    2024年01月19日
    浏览(52)
  • 《设计模式的艺术》笔记 - 组合模式

            组合模式组合多个对象形成树形结构以表示具有“部分-整体”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,又可以称为“部分—整体”(Part-Whole)模式,它是一种对象结构型模式。 myclass.h myclass.cpp main.cpp  

    2024年01月19日
    浏览(45)
  • 《设计模式的艺术》笔记 - 装饰模式

            装饰模式动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。装饰模式是一种对象结构型模式。  myclass.h myclass.cpp main.cpp         1. 对于扩展一个对象的功能,装饰模式比继承更加灵活性,不会导致类的个数急剧增加

    2024年01月19日
    浏览(51)
  • 《设计模式的艺术》笔记 - 桥接模式

            桥接模式将抽象部分与其实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体模式或接口模式 myclass.h myclass.cpp main.cpp         1. 分离抽象接口及其实现部分。桥接模式使用“对象间的关联关系”解耦了抽象和实现之间固有的绑定关系,

    2024年01月18日
    浏览(56)
  • 《设计模式的艺术》笔记 - 建造者模式

            建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造这模式是一种对象创建型模式。 myclass.h myclass.cpp main.cpp         优点:         1. 在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建

    2024年01月16日
    浏览(40)
  • 《设计模式的艺术》笔记 - 享元模式

            享元模式运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,是一种对象结构型模式。 myclass.

    2024年01月19日
    浏览(46)
  • 《设计模式的艺术》笔记 - 抽象工厂模式

            提供了一个创建一系列相关或相互依赖的对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。         在抽象工厂模式中,每个具体工厂都提供了多个工厂方法用于产生多种不同类型的产品,这些产品构成了一个产品族。

    2024年01月16日
    浏览(37)
  • 《设计模式的艺术》笔记 - 单例模式

            单例模式优点是可以确保系统中只存在单个对象实例,缺点是不便扩展,一定程度上违背单一原则,既提供业务方法,又提供创建对象方法         在类加载的时候就创建好对象,获取对象时直接返回即可         在类加载的时候没有创建对象,第一次获取对象

    2024年02月02日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包