设计模式 5 原型模式

设计模式 5

  • 创建型模式(5):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
  • 结构型模式(7):适配器模式、桥接模式、组合模式、装饰者模式、外观模式、享元模式、代理模式
  • 行为型模式(11):责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式

文章目录

  • [设计模式 5](#设计模式 5)
    • [原型模式(Prototype Pattern)](#原型模式(Prototype Pattern))
      • [1 定义](#1 定义)
      • [2 结构](#2 结构)
      • [3 示例代码](#3 示例代码)
      • [4 特点](#4 特点)
      • [5 适用场景](#5 适用场景)
      • [6 与其他模式对比](#6 与其他模式对比)

原型模式(Prototype Pattern)

1 定义

原型模式允许一个对象通过复制自身来创建新的对象。这种模式提供了一种创建对象的快捷方式,尤其适用于创建代价较高的对象。

2 结构

原型模式的结构包含以下角色:

  • 原型(Prototype): 定义一个可以克隆自身的接口。
  • 具体原型(ConcretePrototype) : 实现 Prototype 接口并能够克隆自身。
  • 客户端(Client) : 通过请求 Prototype 对象复制自身来创建新对象。

UML 类图

scss 复制代码
+----------------------+                +-------------------------+
|      Prototype       |<---------------|      ConcretePrototype  |
+----------------------+                +-------------------------+
| + Clone(): Prototype |                | + Clone(): Prototype    |
+----------------------+                +-------------------------+
         /|\                                           |
          |                                            |
          |                                            |
+---------------------+                        +---------------------------------+
|      Client         |                        |      AnotherConcretePrototype   |
+---------------------+                        +---------------------------------+
| + Operation()       |                        | + Clone(): Prototype            |
+---------------------+                        +---------------------------------+

3 示例代码

原型模式的核心在于实现对象的深拷贝或浅拷贝。以下是一个实现原型模式的简单示例,其中我们克隆一个对象来创建新的对象。

原型接口

csharp 复制代码
// 原型接口
public abstract class Prototype
{
    public abstract Prototype Clone();
}

具体原型类

csharp 复制代码
// 具体原型类
public class ConcretePrototype : Prototype
{
    public string Name { get; set; }

    public ConcretePrototype(string name)
    {
        Name = name;
    }

    // 实现克隆方法
    public override Prototype Clone()
    {
        return (Prototype)this.MemberwiseClone(); // 浅拷贝
    }
}

客户端代码

csharp 复制代码
class Program
{
    static void Main(string[] args)
    {
        // 创建一个原型对象
        ConcretePrototype prototype1 = new ConcretePrototype("Prototype 1");

        // 克隆原型对象
        ConcretePrototype clonedPrototype = (ConcretePrototype)prototype1.Clone();

        // 显示克隆对象的属性
        Console.WriteLine("Original Prototype Name: " + prototype1.Name);
        Console.WriteLine("Cloned Prototype Name: " + clonedPrototype.Name);

        // 修改克隆对象的属性
        clonedPrototype.Name = "Cloned Prototype 1";

        Console.WriteLine("\nAfter modification:");
        Console.WriteLine("Original Prototype Name: " + prototype1.Name);
        Console.WriteLine("Cloned Prototype Name: " + clonedPrototype.Name);
    }
}

在这个例子中,ConcretePrototype 是具体的原型类,实现了 Clone 方法。Clone 方法使用 MemberwiseClone 来执行浅拷贝,这意味着对象的成员变量会被复制,但对象的引用类型成员变量依然指向同一个内存地址。

浅拷贝与深拷贝:

  • 浅拷贝(Shallow Copy): 复制对象时,只复制对象的基本数据类型成员变量,对于引用类型成员变量,只复制引用,不复制引用指向的对象。
  • 深拷贝(Deep Copy): 复制对象时,不仅复制对象的基本数据类型成员变量,也复制引用类型成员变量所引用的对象,生成全新的副本。

深拷贝的实现

要实现深拷贝,可以在 Clone 方法中手动复制引用类型的成员变量,或者通过序列化和反序列化来实现。

csharp 复制代码
// 实现深拷贝的具体原型类
[Serializable]
public class DeepConcretePrototype : Prototype
{
    public string Name { get; set; }
    public List<string> Features { get; set; }

    public DeepConcretePrototype(string name, List<string> features)
    {
        Name = name;
        Features = features;
    }

    public override Prototype Clone()
    {
        // 深拷贝:通过序列化和反序列化
        using (MemoryStream stream = new MemoryStream())
        {
            IFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, this);
            stream.Seek(0, SeekOrigin.Begin);
            return (Prototype)formatter.Deserialize(stream);
        }
    }
}

4 特点

  • 优点:

    • 减少对象创建的成本: 尤其是当对象的创建代价很高时,通过克隆一个现有的对象可以减少资源消耗。

    • 避免复杂对象的重复创建: 当创建复杂对象需要设置大量参数或步骤时,原型模式可以避免重复工作。

    • 易于扩展: 可以通过继承现有原型类来扩展新的克隆行为,而无需修改现有代码。

  • 缺点:

    • 深拷贝实现复杂: 如果对象包含复杂的引用关系,深拷贝的实现可能会很复杂。

    • 容易引起混淆: 如果在系统中有多个原型对象,可能会导致代码的可读性降低,增加理解难度。

5 适用场景

  • 对象创建代价高: 当一个对象的创建成本高昂(如初始化配置、数据库连接等)时,使用原型模式可以减少创建成本。
  • 对象结构复杂: 对于具有复杂结构的对象,使用原型模式可以避免重复的创建工作。
  • 需要多个类似实例: 当需要生成一系列相似对象时,使用原型模式可以通过克隆现有对象来快速创建新对象。

6 与其他模式对比

  • 与工厂模式的区别: 工厂模式是通过实例化来创建对象,而原型模式是通过克隆已有对象来创建新对象。
  • 与建造者模式的区别: 建造者模式关注的是一步步构建复杂对象,而原型模式是通过复制现有对象来创建新对象。

原型模式非常适合在对象创建复杂或成本较高的场景下使用,它通过克隆来简化对象的创建过程并提高性能。

相关推荐
willow3 天前
Axios由浅入深
设计模式·axios
七月丶5 天前
别再手动凑 PR 了:这个 AI Skill 会按仓库习惯自动建分支、拆提交、提 PR
人工智能·设计模式·程序员
刀法如飞5 天前
从程序员到架构师:6大编程范式全解析与实践对比
设计模式·系统架构·编程范式
九狼5 天前
Flutter + Riverpod +MVI 架构下的现代状态管理
设计模式
静水流深_沧海一粟5 天前
04 | 别再写几十个参数的构造函数了——建造者模式
设计模式
StarkCoder5 天前
从UIKit到SwiftUI的迁移感悟:数据驱动的革命
设计模式
阿星AI工作室6 天前
给openclaw龙虾造了间像素办公室!实时看它写代码、摸鱼、修bug、写日报,太可爱了吧!
前端·人工智能·设计模式
_哆啦A梦6 天前
Vibe Coding 全栈专业名词清单|设计模式·基础篇(创建型+结构型核心名词)
前端·设计模式·vibecoding
阿闽ooo10 天前
中介者模式打造多人聊天室系统
c++·设计模式·中介者模式