原型模式详解

简介: 原型模式是一种创建型设计模式,通过复制已有对象来创建新对象,而非直接实例化类。这种方式特别适用于对象创建成本高或需要深复制的场景。原型模式的优点包括性能优化、简化对象创建和动态增加产品种类,但也有深浅复制问题和对克隆方法的依赖等缺点。适用于对象创建成本高、状态动态变化和避免工厂模式复杂性的场景。核心角色包括抽象原型、具体原型和客户端。

原型模式详解

定义

原型模式(Prototype Pattern)是一种创建型设计模式,它允许通过复制已有对象来创建新对象,而不是直接通过实例化类来创建。

这种模式提供了一种创建对象的快捷方式,尤其适用于对象创建成本高或需要深复制的场景。


原型模式的特点

优点

  1. 性能优化:通过复制已有对象,避免昂贵的资源初始化操作。
  2. 简化对象创建:隐藏复杂的构造过程,减少耦合。
  3. 动态增加产品种类:无需修改代码,可以通过复制现有对象快速生成新对象。

缺点

  1. 深浅复制问题:需要对对象中包含的引用类型进行深复制,增加实现复杂性。
  2. 对克隆方法的依赖:每个类都需要实现自己的克隆逻辑,可能增加代码量。

适用场景

  1. 对象创建成本高
    比如通过网络加载大数据对象或复杂初始化的对象。
  2. 对象状态的动态变化
    比如需要复制对象以保存当前状态。
  3. 需要避免工厂模式的复杂性
    通过复制对象创建实例比工厂方法更简单直接。
  4. 游戏开发
    克隆游戏角色、技能等对象,避免重复创建。

原型模式的结构

核心角色

  1. 抽象原型(Prototype):定义一个接口,用于克隆自身。
  2. 具体原型(Concrete Prototype):实现克隆方法,并返回自身的副本。
  3. 客户端(Client):通过调用原型对象的克隆方法来创建新对象。

使用案例

案例 1:文档编辑器

在图形化编辑器中复制图形或文档内容。

案例 2:数据库记录缓存

复制已有的数据记录以快速生成新记录。

案例 3:游戏角色克隆

玩家角色或敌人角色的复制,避免重复初始化。


原型模式的实现

C++ 实现

#include <iostream>
#include <memory>
#include <string>

// 抽象原型
class Prototype {
public:
   virtual std::unique_ptr<Prototype> clone() const = 0;
   virtual void display() const = 0;
   virtual ~Prototype() = default;
};

// 具体原型 1
class ConcretePrototypeA : public Prototype {
   std::string state;
public:
   ConcretePrototypeA(const std::string& s) : state(s) {}
   std::unique_ptr<Prototype> clone() const override {
       return std::make_unique<ConcretePrototypeA>(*this); // 浅复制
   }
   void display() const override {
       std::cout << "ConcretePrototypeA with state: " << state << std::endl;
   }
};

// 具体原型 2
class ConcretePrototypeB : public Prototype {
   int value;
public:
   ConcretePrototypeB(int v) : value(v) {}
   std::unique_ptr<Prototype> clone() const override {
       return std::make_unique<ConcretePrototypeB>(*this); // 浅复制
   }
   void display() const override {
       std::cout << "ConcretePrototypeB with value: " << value << std::endl;
   }
};

// 客户端代码
int main() {
   std::unique_ptr<Prototype> prototypeA = std::make_unique<ConcretePrototypeA>("Initial State");
   std::unique_ptr<Prototype> cloneA = prototypeA->clone();
   cloneA->display();

   std::unique_ptr<Prototype> prototypeB = std::make_unique<ConcretePrototypeB>(42);
   std::unique_ptr<Prototype> cloneB = prototypeB->clone();
   cloneB->display();

   return 0;
}


C# 实现

using System;

// 抽象原型
public abstract class Prototype {
   public abstract Prototype Clone();
   public abstract void Display();
}

// 具体原型 1
public class ConcretePrototypeA : Prototype {
   private string State;

   public ConcretePrototypeA(string state) {
       State = state;
   }

   public override Prototype Clone() {
       return (Prototype)this.MemberwiseClone(); // 浅复制
   }

   public override void Display() {
       Console.WriteLine($"ConcretePrototypeA with state: {State}");
   }
}

// 具体原型 2
public class ConcretePrototypeB : Prototype {
   private int Value;

   public ConcretePrototypeB(int value) {
       Value = value;
   }

   public override Prototype Clone() {
       return (Prototype)this.MemberwiseClone(); // 浅复制
   }

   public override void Display() {
       Console.WriteLine($"ConcretePrototypeB with value: {Value}");
   }
}

// 客户端代码
class Program {
   static void Main(string[] args) {
       Prototype prototypeA = new ConcretePrototypeA("Initial State");
       Prototype cloneA = prototypeA.Clone();
       cloneA.Display();

       Prototype prototypeB = new ConcretePrototypeB(42);
       Prototype cloneB = prototypeB.Clone();
       cloneB.Display();
   }
}


原型模式的类图

原型模式的扩展

1. 深复制与浅复制

  • 浅复制:复制对象时,引用类型的字段仍指向同一个对象。
  • 深复制:复制对象时,同时复制所有引用类型的字段内容,生成新的对象实例。

2. 结合注册表模式

将原型对象注册到一个集中管理的注册表中,客户端可以通过键值对直接获取克隆。

3. 与其他模式结合

  • 与工厂模式结合:工厂提供原型的注册和克隆服务。
  • 与装饰器模式结合:克隆对象后对其进行装饰,动态添加功能。

原型模式与其他模式对比

特性 原型模式 工厂模式
关注点 通过复制现有对象创建新对象 通过实例化类创建对象
适用场景 对象初始化复杂或需要复制时 创建独立新对象时
灵活性 更高(动态克隆对象) 较低(需修改工厂实现)

总结

原型模式通过复制已有对象,提供了一种高效的对象创建方式,适合对象初始化开销高或需要频繁复制的场景。其核心在于克隆方法的实现,正确处理深浅复制关系是关键。在实践中,原型模式通常与其他模式结合使用,如工厂模式、注册表模式,进一步提高代码的灵活性和复用性。

目录
相关文章
|
10月前
|
设计模式 算法 定位技术
策略模式(Strategy Pattern)
策略模式(Strategy Pattern)是一种行为型设计模式,允许在运行时选择算法或行为,而不是在编译时确定。通过将具体算法封装成独立的类,并通过统一接口与客户端交互,实现算法的动态替换,避免代码重复和复杂条件语句。适用于支付方式切换、导航路径选择等场景。
294 1
|
10月前
|
网络协议 算法 网络性能优化
第十一问:TCP的窗口机制是什么?
TCP的窗口机制是实现流量控制和拥塞控制的重要手段,主要包括滑动窗口、接收窗口(rwnd)和拥塞窗口(cwnd)。滑动窗口定义了发送方允许发送的数据范围,接收窗口控制接收方的缓冲区容量,拥塞窗口防止网络拥塞。这些窗口通过动态调整,确保数据传输的高效性和可靠性。
867 1
|
10月前
|
存储 安全 Linux
全平台免费的在线笔记本(支持markdown、mermaid)
StackEdit是一款基于浏览器的Markdown编辑器,支持跨平台使用,无需安装,可将笔记存储在gitee、github等平台上。其优势包括内容安全免费、多平台同步、离线可用、支持UML图和流程图绘制等。通过简单的步骤即可完成注册、登录和笔记创作,并能轻松实现在线共享。
2352 1
|
10月前
|
XML 设计模式 JSON
模板方法模式(Template Method Pattern)
模板方法模式是一种行为型设计模式,定义一个操作中的算法骨架,将某些步骤的实现延迟到子类。子类可以在不改变算法结构的情况下重新定义算法的某些步骤。适用于多个类有相似操作流程且部分步骤需要定制的场景。优点包括高复用性、扩展性强和清晰明确;缺点是灵活性降低和可能引入性能开销。示例包括文件解析和策略模式的对比。
156 3
模板方法模式(Template Method Pattern)
|
10月前
|
存储 设计模式 算法
命令模式(Command Pattern)
命令模式是一种行为型设计模式,将请求封装为对象,实现参数化请求、支持撤销操作和记录日志。适用于需要解耦发送者和接收者的场景,如智能家居系统中的遥控器控制电灯开关并支持撤销功能。优点包括解耦、支持撤销与恢复操作,但过度使用会增加系统复杂度。
168 7
|
10月前
|
设计模式 C# C++
责任链模式(Chain of Responsibility Pattern)
责任链模式是一种行为型设计模式,允许多个对象按顺序处理请求,直到某个对象处理为止。适用于多个对象可能处理同一请求的场景,如请假审批流程。优点是灵活性高、降低耦合,但责任链过长可能影响性能。
300 3
|
10月前
|
设计模式 监控 数据库
代理模式(Proxy Pattern)
代理模式(Proxy Pattern)是一种设计模式,通过一个中间对象(代理)来间接访问目标对象,以控制访问权限或添加额外功能。常见的代理类型包括远程代理、虚拟代理、保护代理和智能引用代理。代理模式常用于延迟加载、权限控制、日志记录等场景,能够提高系统的灵活性和安全性。
406 3
|
10月前
|
设计模式 C# C++
建造者模式详解
建造者模式是一种创建型设计模式,通过将对象的构造与表示分离,使得同样的构建过程可以创建不同的对象。它适用于复杂对象的构建,如汽车制造、软件配置生成等场景。该模式的核心角色包括抽象建造者、具体建造者、产品和指挥者。优点包括解耦构造和表示、代码复用性强、易于扩展;缺点是增加代码复杂度,对产品组成部分有依赖。
246 3
|
10月前
|
设计模式 数据库 C#
外观模式(Facade Pattern)
外观模式(Facade Pattern)是一种结构型设计模式,为子系统中的一组接口提供一个一致的接口。它通过一个高层接口简化子系统的复杂性,使客户端更容易使用。外观模式的核心角色包括外观(Facade)和子系统(Subsystems),主要优点是降低复杂性和松耦合,适用于简化接口、分层设计和遗留代码集成等场景。
137 2
|
10月前
|
设计模式 IDE 数据可视化
UML中类图的介绍与使用
类图是 UML 中用于展示系统静态结构的重要工具,包括类、接口及其关系。类图有助于系统可视化、团队沟通、发现设计问题、文档化系统和辅助开发工具。类图的三大元素是类、接口和关系,其中关系又细分为关联、聚合、组合、继承、实现和依赖。类图在设计模式学习和实际开发中非常重要,许多现代 IDE 都支持从类图生成代码或从代码生成类图。
490 2
下一篇
oss教程