設計模式 | 原型模式

原型模式通過克隆機制實現對象高效創建,是性能敏感場景的利器。本文結合C++示例詳解實現原理、深拷貝陷阱、應用場景,并與工廠模式對比分析。

為何需要原型模式?

當遇到以下場景時,傳統構造方法面臨挑戰:

  1. 創建成本高:對象初始化需訪問數據庫/讀取文件(如游戲角色加載資源)

  2. 狀態復雜:對象包含多層嵌套結構(如DOM樹節點)

  3. 動態配置:運行時需基于現有對象微調生成新對象

原型模式優勢

  • 避開重復初始化開銷

  • 免去工廠類繼承體系

  • 支持運行時動態對象生成


原型模式核心概念

用原型實例指定創建對象的種類,并通過拷貝這些原型創建新的對象


C++ 深度實現(解決淺拷貝陷阱)

基礎實現

#include <iostream>
#include <memory>// 抽象原型
class IPrototype {
public:virtual ~IPrototype() = default;virtual std::unique_ptr<IPrototype> clone() const = 0;virtual void render() const = 0;
};// 具體原型:游戲敵人角色
class Enemy : public IPrototype {
public:Enemy(int hp, int dmg, std::string model) : hp_(hp), damage_(dmg), model_(std::move(model)) {// 模擬高成本資源加載std::cout << "Loading 3D model: " << model_ << "...\n";}std::unique_ptr<IPrototype> clone() const override {return std::make_unique<Enemy>(*this); // 調用拷貝構造}void render() const override {std::cout << "Enemy[HP:" << hp_ << " DMG:" << damage_<< " MODEL:" << model_ << "]\n";}void setHP(int hp) { hp_ = hp; }private:int hp_;int damage_;std::string model_;  // 字符串自動深拷貝
};

含指針成員的深拷貝解決方案

class Weapon {
public:Weapon(std::string name, int dmg) : name_(std::move(name)), base_dmg_(dmg) {}std::unique_ptr<Weapon> clone() const {return std::make_unique<Weapon>(*this);}
private:std::string name_;int base_dmg_;
};class ArmedEnemy : public IPrototype {
public:ArmedEnemy(int hp, std::unique_ptr<Weapon> weapon): hp_(hp), weapon_(std::move(weapon)) {}// 深拷貝關鍵:遞歸克隆指針成員std::unique_ptr<IPrototype> clone() const override {auto new_weapon = weapon_->clone();return std::make_unique<ArmedEnemy>(hp_, std::move(new_weapon));}private:int hp_;std::unique_ptr<Weapon> weapon_;  // 需特殊處理
};

具體使用示例

int main() {// 1. 初始化原型對象(高成本操作)auto skeleton_prototype = std::make_unique<Enemy>(100, 15, "skeleton.fbx");// 2. 批量生成敵人(零初始化成本)std::vector<std::unique_ptr<IPrototype>> enemies;for (int i = 0; i < 5; ++i) {auto new_enemy = skeleton_prototype->clone();dynamic_cast<Enemy*>(new_enemy.get())->setHP(80); // 差異化調整enemies.push_back(std::move(new_enemy));}// 3. 驗證獨立狀態enemies[0]->render(); // HP:80skeleton_prototype->render(); // HP:100 (原型不受影響)return 0;
}

應用場景與典型案例

場景案例原型模式作用
游戲開發批量生成同類型敵人/NPC避免重復加載3D模型/紋理
文檔編輯復制復雜圖表對象保持格式和數據的完整性
機器學習創建相似配置的模型實例快速實驗不同超參數
撤銷/重做保存對象歷史狀態通過克隆實現狀態快照

優缺點對比分析

?優勢

  • 性能提升:規避昂貴初始化操作

  • 動態性:運行時增減產品對象

  • 簡化結構:無需工廠類繼承體系

陷阱

  • 深拷貝問題:指針成員需遞歸克隆

  • 循環引用:復雜對象圖可能導致拷貝死循環

  • 初始化限制:克隆無法執行構造函數邏輯


與其他創建型模式對比

模式特點適用場景
原型模式通過克隆現有對象創建對象創建成本高或狀態復雜
工廠方法子類決定實例化對象類層次結構穩定
抽象工廠創建相關對象家族需要保證產品兼容性
建造者分步構造復雜對象對象包含多個創建步驟

選擇原則:當系統需要動態生成對象或避免初始化開銷時,優先選擇原型模式


最佳實踐

  1. 實現Clone接口:明確標識可克隆對象

  2. 深拷貝防御:對指針/引用類型實現遞歸克隆

  3. 原型管理器:使用注冊表管理常用原型

    class PrototypeRegistry {std::unordered_map<std::string, std::unique_ptr<IPrototype>> prototypes_;
    public:void add(const std::string& key, std::unique_ptr<IPrototype> proto) {prototypes_[key] = std::move(proto);}std::unique_ptr<IPrototype> clone(const std::string& key) {return prototypes_.at(key)->clone();}
    };

“原型模式不是從零開始構造對象,而是通過克隆現有實例來高效創建新對象,它是面向對象設計中復制與復用對象實例的巧妙捷徑。“ - 設計模式實踐者

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/86602.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/86602.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/86602.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Go 語言中的單元測試

1、如何編寫單元測試 在任何生產級別的項目開發中&#xff0c;單元測試都扮演著至關重要的角色。盡管許多初創項目在早期可能忽略了它&#xff0c;但隨著項目逐漸成熟并成為核心業務&#xff0c;為其編寫健壯的單元測試是保障代碼質量和項目穩定性的必然選擇。本文將帶您快速掌…

8. 接口專業測試報告生成pytest-html

pytest-html 終極指南&#xff1a;打造專業級接口測試報告 在接口自動化測試中&#xff0c;清晰的測試報告是質量保障的關鍵。本文將深入解析如何通過pytest-html插件生成專業級測試報告。 一、核心安裝與基礎使用 快速安裝&#xff08;國內鏡像&#xff09; pip install -i …

Day45 Tensorboard使用介紹

目錄 一、tensorboard的發展歷史和原理及基本操作 1.1 發展歷史 1.2 tensorboard的原理 1.3 日志目錄自動管理 1.4 記錄標量數據&#xff08;Scalar&#xff09; 1.5 可視化模型結構&#xff08;Graph&#xff09; 1.6 可視化圖像&#xff08;Image&#xff09; 1.7 記…

用AI給AR加“智慧”:揭秘增強現實智能互動的優化秘密

用AI給AR加“智慧”:揭秘增強現實智能互動的優化秘密 引子:增強現實,到底還能怎么更聰明? 還記得當年Pokmon GO火爆全球的場景嗎?玩家們手機對準街頭,虛擬小精靈活靈活現地跳出來,那就是增強現實(AR)最經典的應用之一。隨著硬件發展和算法進步,AR正逐步從“炫酷玩具…

1 Studying《Computer Vision: Algorithms and Applications 2nd Edition》1-5

目錄 Chapter 1 Introduction 1.1 什么是計算機視覺&#xff1f; 1.2 簡史 1.3 書籍概述 1.4 樣本教學大綱 1.5 符號說明 1.6 其他閱讀材料 Chapter 2 Image formation 2.1 幾何基本元素和變換 2.2 光度圖像形成 2.3 數碼相機 2.4 其他閱讀材料 2.5 練習 Chapter…

Augment插件macOS

macOS蘋果電腦vscode-augment免費額度續杯跑滿 前言 在AI輔助編程日益普及的今天&#xff0c;Augment作為VS Code中的智能代碼助手&#xff0c;為開發者提供了強大的代碼生成和優化功能。然而&#xff0c;免費版本每月300次的使用限制往往讓重度用戶感到困擾。本文將詳細介紹如…

OpenCV CUDA模塊設備層-----創建一個“常量指針訪問器” 的工具函數constantPtr()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 在 CUDA 設備端模擬一個“指向常量值”的虛擬指針訪問器&#xff0c;使得你可以像訪問數組一樣訪問一個固定值。 這在某些核函數中非常有用&…

Python:操作 Excel 刪除工作簿

??親愛的技術愛好者們,熱烈歡迎來到 Kant2048 的博客!我是 Thomas Kant,很開心能在CSDN上與你們相遇~?? 本博客的精華專欄: 【自動化測試】 【測試經驗】 【人工智能】 【Python】 Python 操作 Excel 系列 讀取單元格數據按行寫入設置行高和列寬自動調整行高和列寬水平…

Python類型注解(Type Hints)的工程實踐指南

一、類型注解的核心價值 代碼可讀性&#xff1a;明確函數輸入輸出類型 靜態檢查&#xff1a;配合mypy提前發現類型錯誤 IDE支持&#xff1a;提升代碼補全和重構能力 文檔替代&#xff1a;類型即文檔的現代編程理念 二、基礎語法規范 def greet(name: str, times: int 1)…

Hadoop RPC 分層設計的哲學:高內聚、低耦合的最佳實踐

Hadoop RPC Hadoop RPC主要分為四個部分&#xff0c;分別是序列化層、函數調用層、網絡傳輸層和服務器端處理框架&#xff0c;實現機制為&#xff1a; 序列化層&#xff1a;主要作用是將結構化對象轉為字節流以便于通過網絡進行傳輸或寫入持久存儲。函數調用層&#xff1a;主…

MybatisPlus-01.MybatisPlus介紹

一.MybatisPlus介紹 MybatisPlus是對Mybatis的增強和升級&#xff0c;但需要注意的是&#xff0c;MybatisPlus并不是取代Mybatis的&#xff0c;而是要做Mybatis最好的合作伙伴。左邊藍色的小鳥就是MybatisPlus的標志。 在MybatisPlus官方頁面上介紹了其特點&#xff0c;首先&am…

人大金倉數據庫jdbc連接jar包kingbase8-8.6.0.jar驅動包最新版下載(不需要積分)

看了網上的很多&#xff0c;都是需要下載積分的 分享一下直接訪問人大金倉官網&#xff0c;下載對應的數據庫jdbc連接jar包kingbase8-8.6.0.jar驅動包&#xff1a; 點擊 服務與支持&#xff0c;然后選擇 下載中心 選擇對應的產品和版本&#xff0c;最后選擇軟件版本 看到有…

cf 禁止http/1.0和http/1.1的訪問 是否會更安全?

使用 Cloudflare&#xff08;CF&#xff09;禁止 HTTP/1.0 和 HTTP/1.1 的訪問&#xff0c;強制客戶端使用 HTTP/2 或更高版本&#xff08;如 HTTP/3&#xff09;&#xff0c;在某些情況下可以提升網站安全性&#xff0c;但也存在權衡和限制。以下是詳細分析&#xff0c;幫你判…

【Docker基礎】Docker容器管理:docker pause詳解

目錄 1 Docker容器管理概述 2 docker pause命令詳解 2.1 命令基本語法 2.2 命令功能解析 2.3 暫停與停止的區別 3 docker pause的工作流程 3.1 工作流程概述 3.2 工作流程詳解 4 docker pause的使用場景 4.1 資源臨時調整 4.2 調試與檢查 4.3 服務維護 4.4 數據備…

Springboot ResponseBodyAdvice 的小妙用

最近公司接觸到了政府項目&#xff0c;在開發完成后&#xff0c;需要對代碼做安全掃描&#xff0c;對系統做安全測試&#xff0c;在安全測試中有一項不合格&#xff0c;就是接口返回錯誤是&#xff0c;錯誤不是瀏覽器級別的&#xff0c;什么意思呢&#xff0c;一般我們都會封裝…

Re:從零開始的文件結構(融合線性表來理解 考研向)

文件管理 & 線性表 文件管理文件的結構無結構文件 有結構文件&#xff08;重點&#xff09;定長與不定長記錄順序文件&#xff08;類線性表&#xff09;它的邏輯結構它的物理結構&#xff08;存儲結構&#xff09;小結 索引順序文件與多級索引順序文件形象化理解&#xff0…

并發基礎7(守護線程)

目錄 1&#xff1a;什么守護線程 2&#xff1a;守護線程使用 3&#xff1a;守護線程案例 1&#xff1a;什么守護線程 守護線程是Java中的一種特殊的線程類型&#xff0c;它為其他線程&#xff08;非守護線程&#xff09;提供后臺支持服務。 在Java多線程編程中&#xff0c…

蜣螂算法+四模型對比!DBO-CNN-BiLSTM-Attention系列四模型多變量時序預測

蜣螂算法四模型對比&#xff01;DBO-CNN-BiLSTM-Attention系列四模型多變量時序預測&#xff08;Matlab完整源碼和數據&#xff09; 目錄 蜣螂算法四模型對比&#xff01;DBO-CNN-BiLSTM-Attention系列四模型多變量時序預測&#xff08;Matlab完整源碼和數據&#xff09;效果一…

服務器的維護技術都有哪些?

服務器的穩定性與可靠性是十分重要的&#xff0c;當服務器出現故障或損壞時&#xff0c;會影響業務的正常運行&#xff0c;還會導致數據丟失給企業帶來巨大的經濟損失&#xff0c;所以大多數的企業通常掌握著有效的服務器維護技術&#xff0c;不僅能夠提高服務器的穩定性&#…

Go 語言并發編程

Go 語言的并發模型是其區別于其他編程語言的重要特性之一&#xff0c;它以簡潔高效的方式解決了現代編程中多核處理器利用和高并發場景的需求。 一、并發與并行&#xff1a;概念與區別 在理解 Go 的并發模型之前&#xff0c;需要明確并發與并行的差異&#xff1a; 并發&…