C++创建型模式之原型模式

news/2024/12/25 1:31:37/

C++ 原型模式(Prototype Pattern)

1. 解决的问题

原型模式(Prototype Pattern)是一种创建型设计模式,用于解决对象创建的问题,特别是在需要创建多个相似对象时,避免使用重复的构造代码。原型模式通过复制已有对象(原型)来创建新对象,而不是通过实例化一个类来创建。

2. 适用场景
  • 当系统需要创建多个相似对象,并且这些对象之间的差异只是部分属性值不同。
  • 当对象的创建过程比较复杂,并且通过复制现有对象可以简化创建过程。
  • 当需要避免使用子类的创建方式来生成对象时。
3. 模式的参与者角色
  • Prototype(抽象原型):声明一个克隆自身的接口。
  • ConcretePrototype(具体原型):实现克隆自身的操作。
  • Client(客户端):使用原型对象来克隆新的对象。
4. 示例代码

假设我们正在开发一个复杂的角色扮演游戏(RPG),游戏中有各种不同的角色,这些角色可以是玩家角色(Player)或敌人角色(Enemy)。每个角色都有不同的属性和能力,例如生命值、攻击力、防御力等。为了简化角色的创建过程,我们可以使用原型设计模式来复制现有的角色,并根据需要进行微调。

角色类图
+----------------+
|   Prototype    |
|----------------|
| + clone()      |
| + print()      |
+----------------+^|
+----------------+
|    Player      |
|----------------|
| + clone()      |
| + print()      |
+----------------+^|
+----------------+
|    Enemy       |
|----------------|
| + clone()      |
| + print()      |
+----------------+

代码
#include <iostream>
#include <string>
#include <memory>
#include <vector>// Prototype 接口
class Prototype {
public:virtual ~Prototype() {}virtual std::unique_ptr<Prototype> clone() const = 0;virtual void print() const = 0;virtual void setHealth(int health) = 0;virtual void setAttack(int attack) = 0;virtual void setDefense(int defense) = 0;
};// BaseCharacter 抽象类
class BaseCharacter : public Prototype {
public:BaseCharacter(std::string name, int health, int attack, int defense): name_(name), health_(health), attack_(attack), defense_(defense) {}void setHealth(int health) override { health_ = health; }void setAttack(int attack) override { attack_ = attack; }void setDefense(int defense) override { defense_ = defense; }void print() const override {std::cout << "Name: " << name_ << ", Health: " << health_<< ", Attack: " << attack_ << ", Defense: " << defense_ << std::endl;}protected:std::string name_;int health_;int attack_;int defense_;
};// Player 具体原型
class Player : public BaseCharacter {
public:Player(std::string name, int health, int attack, int defense): BaseCharacter(name, health, attack, defense) {}std::unique_ptr<Prototype> clone() const override {return std::make_unique<Player>(*this);}
};// Enemy 具体原型
class Enemy : public BaseCharacter {
public:Enemy(std::string name, int health, int attack, int defense): BaseCharacter(name, health, attack, defense) {}std::unique_ptr<Prototype> clone() const override {return std::make_unique<Enemy>(*this);}
};// 客户端代码
int main() {// 创建原型对象auto playerPrototype = std::make_unique<Player>("Hero", 100, 20, 15);auto enemyPrototype = std::make_unique<Enemy>("Goblin", 50, 10, 5);// 创建角色列表std::vector<std::unique_ptr<Prototype>> characters;// 克隆玩家角色auto player1 = playerPrototype->clone();player1->setHealth(80); // 微调生命值characters.push_back(std::move(player1));auto player2 = playerPrototype->clone();player2->setHealth(90); // 微调生命值player2->setAttack(25); // 微调攻击力characters.push_back(std::move(player2));// 克隆敌人角色auto enemy1 = enemyPrototype->clone();characters.push_back(std::move(enemy1));auto enemy2 = enemyPrototype->clone();enemy2->setHealth(60); // 微调生命值enemy2->setAttack(15); // 微调攻击力characters.push_back(std::move(enemy2));// 打印所有角色信息for (const auto& character : characters) {character->print();}return 0;
}

代码说明
  1. Prototype 接口定义了克隆和打印方法,以及设置角色属性的方法。
  2. BaseCharacter 是一个抽象类,实现了 Prototype 接口的通用部分,包括角色属性的设置和打印方法。
  3. Player 和 Enemy 是具体原型类,继承自 BaseCharacter,并实现了 clone 方法。
  4. Client 在 main 函数中创建了原型对象,并通过克隆这些原型对象来创建新的角色。客户端可以根据需要微调角色的属性。

总结

通过原型设计模式,我们可以轻松地复制现有角色,避免了重复的构造代码,并且可以根据需要对克隆的角色进行微调。这种模式在复杂的游戏场景中非常有用,特别是在需要创建多个相似角色时。

原型模式与 C++ 拷贝构造函数的相似性与不同点

相似性
  1. 对象复制

    • 原型模式原型模式的核心思想是通过复制已有对象来创建新对象。
    • 拷贝构造函数:拷贝构造函数用于从已有对象创建一个新对象。
  2. 避免重复构造

    • 原型模式:避免了重复的构造代码,通过复制已有对象来创建新对象。
    • 拷贝构造函数:避免了重复的构造代码,通过复制已有对象来创建新对象。
  3. 对象状态的复用

    • 原型模式:可以复用已有对象的状态来创建新对象。
    • 拷贝构造函数:可以复用已有对象的状态来创建新对象。
不同点
  1. 设计模式 vs. 语言特性

    • 原型模式:是一种设计模式,属于面向对象编程的设计原则之一。
    • 拷贝构造函数:是 C++ 语言的一个特性,用于实现对象的复制。
  2. 接口定义

    • 原型模式:通常定义一个 clone() 方法,用于克隆对象。
    • 拷贝构造函数:是类的构造函数,定义为 ClassName(const ClassName& other),用于从已有对象创建新对象。
  3. 实现方式

    • 原型模式:可以由程序员显式实现 clone() 方法,并在方法内部调用拷贝构造函数或赋值操作符。
    • 拷贝构造函数:由编译器自动生成或由程序员显式实现。
  4. 灵活性

    • 原型模式:提供了更灵活的对象复制机制,可以在运行时选择不同的原型进行复制。
    • 拷贝构造函数:是类的固有特性,无法在运行时选择不同的构造方式。
  5. 使用场景

    • 原型模式:适用于需要创建多个相似对象,并且这些对象之间的差异只是部分属性值不同。
    • 拷贝构造函数:适用于任何需要从已有对象创建新对象的场景。
示例代码
#include <iostream>
#include <string>
#include <memory>// 使用原型模式的类
class Prototype {
public:virtual ~Prototype() {}virtual std::unique_ptr<Prototype> clone() const = 0;virtual void print() const = 0;
};class ConcretePrototype : public Prototype {
public:ConcretePrototype(std::string name) : name_(name) {}std::unique_ptr<Prototype> clone() const override {return std::make_unique<ConcretePrototype>(*this);}void print() const override {std::cout << "ConcretePrototype: " << name_ << std::endl;}private:std::string name_;
};// 使用拷贝构造函数的类
class CopyConstructorExample {
public:CopyConstructorExample(std::string name) : name_(name) {}CopyConstructorExample(const CopyConstructorExample& other) : name_(other.name_) {std::cout << "Copy Constructor Called" << std::endl;}void print() const {std::cout << "CopyConstructorExample: " << name_ << std::endl;}private:std::string name_;
};int main() {// 原型模式示例auto prototype1 = std::make_unique<ConcretePrototype>("Prototype1");auto clone1 = prototype1->clone();clone1->print();// 拷贝构造函数示例CopyConstructorExample example1("Example1");CopyConstructorExample example2 = example1;example2.print();return 0;
}

总结

  • 相似性原型模式和拷贝构造函数都用于对象的复制,避免了重复的构造代码。
  • 不同点原型模式是一种设计模式,通过 clone() 方法实现对象复制;拷贝构造函数是 C++ 语言特性,通过 ClassName(const ClassName& other) 实现对象复制。原型模式提供了更灵活的对象复制机制。

http://www.ppmy.cn/news/1557875.html

相关文章

【Rust自学】6.1. 定义枚举

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 6.1.1. 什么是枚举 枚举允许我们列举所有可能的值来定义一个类型。这与其他编程语言中的枚举类似&#xff0c;但 Rust 的枚举更加灵活和强…

深入解析 Apache APISIX

以下是“第一部分&#xff1a;背景与概述”的示例写作内容&#xff0c;供你参考和使用。你可根据实际需求和篇幅进行增删或细化。 一、背景与概述 1. 高性能动态网关的意义 1.1 微服务架构下的网关角色与价值 随着微服务架构在企业级应用中日益普及&#xff0c;系统被拆分为…

机器学习-逻辑回归和softmax回归

文章目录 逻辑回归逻辑回归算法表达式模型训练逻辑回归做多分类 softmax回归模型实例训练模型 注意代码 逻辑回归 logistic regression 并不是回归任务的算法&#xff0c;而是属于分类任务算法 逻辑回归算法表达式 一个 型曲线&#xff08;Sigmoid函数&#xff09;&#xff0…

WordPress源码解析-数据库表结构

WordPress是一个功能强大的内容管理系统&#xff0c;它使用MySQL数据库来存储和管理网站的内容、用户和配置信息。作为WordPress开发者&#xff0c;了解WordPress数据库的结构和各表的作用至关重要&#xff0c;因为这将帮助您更好地开发插件和主题&#xff0c;以及执行高级数据…

C++设计模式:享元模式 (附文字处理系统中的字符对象案例)

什么是享元模式&#xff1f; 享元模式是一个非常实用的结构型设计模式&#xff0c;它的主要目的是节省内存&#xff0c;尤其在需要创建大量相似对象时。 通俗解释&#xff1a; 想象我们在写一本书&#xff0c;每个字母都需要表示出来。如果每个字母都单独用对象表示&#xff…

小程序将对象通过url传递到下个页面

// 假设有一个对象需要传递 const obj { name: 张三, age: 25 };// 将对象转换为 JSON 字符串并编码 const objStr encodeURIComponent(JSON.stringify(obj));// 使用 wx.navigateTo 跳转并传递参数 wx.navigateTo({url: /pages/targetPage/targetPage?data${objStr}, });注…

Android Vendor Overlay机制

背景介绍&#xff1a; 看Android 15版本更新时&#xff0c;"Android 15 deprecates vendor overlay"。 猜想这个vendor overlay是之前用过的settings overlay&#xff0c; 不过具体是怎么回事呢&#xff1f; 目录 Vendor Overlay介绍 Vendor Overlay工作原理 Ven…

pytorch MoE(专家混合网络)的简单实现。

专家混合&#xff08;Mixture of Experts, MoE&#xff09;是一种深度学习模型架构&#xff0c;通常用于处理大规模数据和复杂任务。它通过将输入分配给多个专家网络&#xff08;即子模型&#xff09;&#xff0c;然后根据门控网络&#xff08;gating network&#xff09;的输出…