原型模式--创建型模式

1、描述

原型是一种创建型设计模式,使你能够复制对象,甚至是复杂对象,而又无需使代码依赖它们所属的类。所有的原型类都必须有一个通用的接口,使得即使在对象所属的具体类未知的情况下也能复制对象。原型对象可以生成自身的完整副本,因为相同类的对象可以相互访问对方的私有成员变量。

2、结构图

  • 原型(Prototype)接口将对克隆方法进行声明。在绝大多数情况下,其中只会有一个名为clone的克隆方法
  • 具体原型(Concrete Prototype)类将实现克隆方法。除了将原始对象的数据复制到克隆体之外,该方法有时还需要处理克隆过程中的极端情况,例如克隆关联对象和梳理递归依赖等等
  • 客户端(Client)可以复制实现原型接口的任何对象

 

3、C++代码

#include <string>
#include <vector>
#include <iostream>
#include <unordered_map>
using std::string;

enum Type {
  PROTOTYPE_1 = 0,
  PROTOTYPE_2
};


//具有克隆功能的测试类,我们将了解如何克隆具有不同类型的字段的值。
class Prototype {
 protected:
  string prototype_name_;
  float prototype_field_;

 public:
  Prototype() {}
  Prototype(string prototype_name)
      : prototype_name_(prototype_name) {
  }
  virtual ~Prototype() {}
  virtual Prototype *Clone() const = 0;
  virtual void Method(float prototype_field) {
    this->prototype_field_ = prototype_field;
    std::cout << "Call Method from " << prototype_name_ << " with field : " << prototype_field << std::endl;
  }
};

//具体原型,实现了Clone方法。该例子中所有的成员直接拷贝即可,如果你在实现中
//使用指针,需要实现拷贝构造函数确保实现深拷贝。
class ConcretePrototype1 : public Prototype {
 private:
  float concrete_prototype_field1_;

 public:
  ConcretePrototype1(string prototype_name, float concrete_prototype_field)
      : Prototype(prototype_name), concrete_prototype_field1_(concrete_prototype_field) {
  }

  //最好使用智能指针
  Prototype *Clone() const override {
    return new ConcretePrototype1(*this);
  }
};

class ConcretePrototype2 : public Prototype {
 private:
  float concrete_prototype_field2_;

 public:
  ConcretePrototype2(string prototype_name, float concrete_prototype_field)
      : Prototype(prototype_name), concrete_prototype_field2_(concrete_prototype_field) {
  }
  Prototype *Clone() const override {
    return new ConcretePrototype2(*this);
  }
};

//在原型工厂中有两个具体的原型类,所以每次你想创建一个新的对象,可以使用现有的克隆出来
class PrototypeFactory {
 private:
  std::unordered_map<Type, Prototype *, std::hash<int>> prototypes_;

 public:
  PrototypeFactory() {
    prototypes_[Type::PROTOTYPE_1] = new ConcretePrototype1("PROTOTYPE_1 ", 50.f);
    prototypes_[Type::PROTOTYPE_2] = new ConcretePrototype2("PROTOTYPE_2 ", 60.f);
  }

  //最好使用智能指针
  ~PrototypeFactory() {
    delete prototypes_[Type::PROTOTYPE_1];
    delete prototypes_[Type::PROTOTYPE_2];
  }

  //注意这里你只需要指定原型的类型,该方法会创建一个这个类型的对象
  Prototype *CreatePrototype(Type type) {
    return prototypes_[type]->Clone();
  }
};

void Client(PrototypeFactory &prototype_factory) {
  std::cout << "Let's create a Prototype 1\n";

  Prototype *prototype = prototype_factory.CreatePrototype(Type::PROTOTYPE_1);
  prototype->Method(90);
  delete prototype;

  std::cout << "\n";

  std::cout << "Let's create a Prototype 2 \n";

  prototype = prototype_factory.CreatePrototype(Type::PROTOTYPE_2);
  prototype->Method(10);

  delete prototype;
}

int main() {
  PrototypeFactory *prototype_factory = new PrototypeFactory();
  Client(*prototype_factory);
  delete prototype_factory;

  return 0;
}

参考

https://refactoringguru.cn/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值