(5).原型模式

news/2025/3/15 20:57:36/文章来源:https://www.cnblogs.com/kitthe/p/18774173
原型模式(Prototype Pattern)是一种创建型设计模式,它允许通过复制现有的对象来创建新的对象实例,而无需直接使用构造函数。原型模式的主要目的是减少对象创建的开销,并且可以通过克隆现有对象来快速生成新对象。
在C#中,原型模式通常通过实现ICloneable接口或自定义克隆方法来实现。下面我们将详细介绍如何在C#中实现原型模式。

原型模式的基本结构

  1. Prototype: 定义一个用于克隆自身的接口。
  2. ConcretePrototype: 实现Prototype接口的具体类,负责克隆自身。
  3. Client: 使用Prototype接口来克隆对象。

示例代码

假设我们要创建一个简单的文档管理系统,其中包含不同类型的文章(如新闻、博客等),并且我们希望通过克隆现有文章来创建新的文章实例。

1. Prototype 接口

using System;public interface IPrototype
{IPrototype Clone();
}

2. ConcretePrototype 实现

public abstract class Article : IPrototype
{public string Title { get; set; }public string Content { get; set; }public abstract IPrototype Clone();public override string ToString(){return $"Title: {Title}, Content: {Content}";}
}public class NewsArticle : Article
{public string Author { get; set; }public override IPrototype Clone(){// 深拷贝:通过序列化和反序列化实现深拷贝return this.MemberwiseClone() as NewsArticle;}public override string ToString(){return base.ToString() + $", Author: {Author}";}
}public class BlogPost : Article
{public string Category { get; set; }public override IPrototype Clone(){// 深拷贝:通过序列化和反序列化实现深拷贝return this.MemberwiseClone() as BlogPost;}public override string ToString(){return base.ToString() + $", Category: {Category}";}
}

3. Client 类

class Program
{static void Main(string[] args){// 创建一个原始的新闻文章NewsArticle originalNews = new NewsArticle{Title = "Breaking News",Content = "This is a breaking news article.",Author = "John Doe"};Console.WriteLine("Original News Article:");Console.WriteLine(originalNews);// 克隆新闻文章NewsArticle clonedNews = (NewsArticle)originalNews.Clone();clonedNews.Title = "Updated Breaking News";Console.WriteLine("\nCloned News Article:");Console.WriteLine(clonedNews);// 创建一个原始的博客文章BlogPost originalBlog = new BlogPost{Title = "How to Use the Prototype Pattern",Content = "This blog post explains how to use the prototype pattern in C#.",Category = "Programming"};Console.WriteLine("\nOriginal Blog Post:");Console.WriteLine(originalBlog);// 克隆博客文章BlogPost clonedBlog = (BlogPost)originalBlog.Clone();clonedBlog.Title = "Advanced Usage of Prototype Pattern";Console.WriteLine("\nCloned Blog Post:");Console.WriteLine(clonedBlog);}
}

输出结果

Original News Article:
Title: Breaking News, Content: This is a breaking news article., Author: John DoeCloned News Article:
Title: Updated Breaking News, Content: This is a breaking news article., Author: John DoeOriginal Blog Post:
Title: How to Use the Prototype Pattern, Content: This blog post explains how to use the prototype pattern in C#., Category: ProgrammingCloned Blog Post:
Title: Advanced Usage of Prototype Pattern, Content: This blog post explains how to use the prototype pattern in C#., Category: Programming

详细说明

  1. IPrototype 接口:
    • 定义了一个Clone方法,用于克隆对象。
  2. Article 抽象类:
    • 提供了公共属性TitleContent,并实现了Clone方法的抽象定义。
  3. NewsArticle 和 BlogPost 类:
    • 这两个类继承自Article,并分别添加了额外的属性(如AuthorCategory)。
    • Clone方法使用MemberwiseClone来进行浅拷贝。如果需要深拷贝,可以使用序列化和反序列化技术。
  4. Client 类:
    • 客户端代码展示了如何使用原型模式来克隆对象,并修改克隆后的对象属性。

浅拷贝与深拷贝

  • 浅拷贝:只复制对象本身,而不复制对象内部引用的对象。MemberwiseClone方法默认实现的是浅拷贝。
  • 深拷贝:不仅复制对象本身,还递归地复制对象内部的所有引用对象。可以通过序列化和反序列化来实现深拷贝。

深拷贝示例

如果你需要实现深拷贝,可以使用以下方法:
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;public static T DeepCopy<T>(T obj)
{using (var ms = new MemoryStream()){var formatter = new BinaryFormatter();formatter.Serialize(ms, obj);ms.Position = 0;return (T)formatter.Deserialize(ms);}
}
然后在Clone方法中调用这个深拷贝方法:
public override IPrototype Clone()
{return DeepCopy(this);
}

原型模式的优点

  1. 性能提升:对于复杂对象的创建,克隆现有对象可能比直接使用构造函数更高效。
  2. 灵活性:可以在运行时动态决定要克隆的对象类型。
  3. 简化对象创建:减少了对具体类的依赖,客户端只需知道如何克隆对象即可。

原型模式的缺点

  1. 深拷贝复杂性:如果对象包含复杂的引用类型,深拷贝可能会变得复杂。
  2. 克隆方法的维护:如果对象的结构发生变化,可能需要更新克隆方法。

总结

原型模式适用于以下场景:
  • 需要频繁创建相似的对象,且创建过程较为复杂。
  • 对象的创建成本较高,希望通过克隆现有对象来提高性能。
  • 需要在运行时动态决定要克隆的对象类型。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/899375.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第十八届全国大学生信息安全竞赛暨第二届“长城杯”铁人三项赛web方向部分wp

第十八届全国大学生信息安全竞赛暨第二届“长城杯”铁人三项赛web方向部分wp hello_web查看源代码发现有两个文件,访问一下Tips是phpinfo 里面可以看到disable_functions hackme.php中$lapUCm=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%…

使用WLAN接口将温度和相对湿度发送到家庭网络web服务器

在本文中,我想利用WLAN接口,为家庭网络中的web服务器提供温度和相对湿度。但是,我将使用物有所值的DHT20传感器和带有SH1106驱动IC的1.3英寸OLED,以尽量减少重复。 但首先是树莓派Pico W的引脚图,以及树莓派Pico和Pico W的区别:虽然外形尺寸和引脚(很大程度上)保持不变,…

【水】洛谷 P3913 (待续)

今天NaN在刷水题时碰到这么一道题:洛谷P3913 https://www.luogu.com.cn/problem/P3913 代码的思路特别简单:用全部格子数 - 没被車侵占的行数 \(\times\) 列数即可. code void solve() {cin >> n >> k;g = h = n;for (ll i = 1; i <= k; i++){cin >> x …

web77笔记(POST+FFI)

web77 命令执行最后一题,php7.4 FFI,php7.4以上才有 https://www.php.net/manual/zh/ffi.cdef.php https://www.php.cn/php-weizijiaocheng-415807.html $ffi = FFI::cdef("int system(const char *command);");//创建一个system对象 $a=/readflag > 1.txt;//没…

day:22 python函数——介绍及自定义函数运用

一.函数的定义 函数是组织好,可以重复使用,用来实现单一,或者关联功能的代码段 二.pycharm中运用的结构三.函数的优点? a.降低代码的冗余 b.增加代码的复用性,提高开发效率 c.提高程序的拓展性 d.把代码片段放在函数当中 四.定义函数 (1)自定义函数 (一)自定义函数 a.函数格式…

英语单词音标重读符号读法作用

比如explicit,重读的是`后面的第一个元音即i

量子网络操作系统 QNodeOS 资料收集

2025年3月14日,通过科技日报的报道知道了这个量子计算领域的重大突破 —— 全球首个量子网络操作系统 QNodeOS 问世。欧洲的量子互联网联盟(QIA)的研究人员2025年3月12日在《自然》(Nature)杂志上发表了论文 An operating system for executing applications on quantum n…

Typora的基本的一些使用用法

markdown 标题 二级标题 (在最前面两个#号加空格) 三级标题 (在最前面三个#号加空格) 字体 Hello,World!(粗体:两边各两个星号) Hello,World!(斜体:两边各一个星号) Hello,World!(粗体加斜体:两边各三个星号) Hello,World!(删除体:两边各两个波浪号) 引用(大于加…

http--nodejs原生web服务

创建http服务const http = require(node:http) const url = require(node:url)http.createServer((req, res) => {}).listen(98, () => {console.log(server is running on port 98) }) 区分请求方法 例如常见的 POST、GET req表示前端的入参(请求参数)。 res 表示后…

Windows server 中 静默安装SQL SERVER 数据库 命令 参数

这篇文章记录一下自己如何在Windows Server Core上安装和配置SQL Server。 安装之前的检查 安装SQL Server的操作系统要求检查 第一件事是需要仔细检查SQL Server的要求文档,这个文档里详细的列出了目前SQL Server支持的操作系统版本,最重要的一条就是检查当你在使用云上的虚…

(3).工厂方法模式

我们接上一个模式的实例: (1).创建水果接口 IFruit:1 namespace 工厂方法模式2 {3 public interface IFruit4 {5 /// <summary>6 /// 水果的单价7 /// </summary>8 double Amount { get; }9 10 11 /// <s…

nestjs Provider

Nest 实现了 IoC 容器,会从入口模块开始扫描,分析 Module 之间的引用关系,对象之间的依赖关系,自动把 provider 注入到目标对象以上部分只是简写{provide: AppService,useClass: AppService }两种注入方式构造器注入属性注入全局模块一般来说,我们都是在需要导出的模块的m…