首页 > 编程语言 >Prototype 原型模式简介与 C# 示例【创建型4】【设计模式来了_4】

Prototype 原型模式简介与 C# 示例【创建型4】【设计模式来了_4】

时间:2023-08-18 10:55:17浏览次数:39  
标签:克隆 示例 C# 创建 Clone 对象 原型 设计模式

〇、简介

1、什么是原型模式?

一句话解释:

  针对比较耗时的对象创建过程,通过原型的 Clone 方法来克隆对象,而非重新创建。

原型设计模式(Prototype Design Pattern)是一种创建型设计模式,其主要目的是通过复制已有对象来创建新的对象,而无需通过实例化类并初始化其属性。这种模式在需要创建相似对象时非常有用,尤其是当创建过程较为复杂或耗时时。

原型设计模式中的 Clone() 方法可以是深拷贝或浅拷贝,具体取决于实现的方式。

官方意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 

 一个比喻:(多个班级与礼堂)

  多个班级需要轮流在礼堂举行活动,门口有海报标注时间,相当于礼堂对象的引用。学校不会为每个班级修一座礼堂,这样太耗时,而是每个班级共用一个礼堂,使用时按照海报的时间即可。

2、优缺点和使用场景

优缺点:

  • 简化对象创建。原型设计模式通过克隆现有对象来创建新对象,避免了重新构造复杂的对象。这样可以简化对象的创建过程,减少了重复代码的编写
  • 提高性能。由于原型设计模式避免了重新执行初始化过程,通过复制现有对象来创建新对象,可以提高系统的性能,特别是在对象创建成本较高的情况下。
  • 隐藏对象创建细节。原型设计模式将对象的创建细节封装在原型对象中,客户端只需通过克隆操作即可创建新对象,无需了解对象创建的具体实现。这样可以降低系统的耦合度,提高代码的灵活性和可维护性
  • 动态添加或删除对象。原型设计模式通过克隆现有对象来创建新对象,可以方便地增加或减少对象的数量,实现了系统的灵活性和可扩展性。

原型设计模式在合适的场景下可以提供很多优点,但在使用时需要注意克隆方法的正确性和对象的深拷贝问题。

  • 需要对每个类进行克隆操作。在使用原型设计模式时,需要为每个类都实现克隆方法,这可能会增加代码量和维护成本。
  • 克隆方法的正确性。实现克隆方法时需要保证被克隆对象的所有成员变量都正确地进行复制,包括基本数据类型和引用类型。如果某个成员变量未正确克隆,可能会导致意外的行为或错误
  • 对象的深拷贝问题。在实现原型设计模式时,需要注意对象的深拷贝问题。如果对象中包含了其他对象的引用,需要确保对这些引用对象也进行递归的克隆操作,以实现真正的深拷贝

适用场景:

  • 创建一个对象的过程非常复杂或者耗时时,可以使用原型设计模式。通过复制现有对象来创建新对象,可以避免重新执行复杂的初始化过程,从而提高性能。
  • 当需要避免与对象创建相关的细节,并希望客户端能够独立于具体类进行实例化时,可以使用原型设计模式。通过原型模式,客户端可以通过复制原型对象来创建新对象,而无需了解对象创建的具体实现。
  • 当系统需要动态地添加或删除一些对象时,可以使用原型设计模式。通过克隆现有对象来创建新对象,可以方便地增加或减少对象的数量。
  • 当希望改变和定制一个对象的结构,同时又希望保持其行为不变时,可以使用原型设计模式。通过克隆对象并对其进行修改,可以快速生成新对象,同时保留原始对象的行为。

实际使用场景举例:

  • 在游戏开发中,角色的创建和管理是一个重要的问题。原型设计模式可以用于创建和管理大量的游戏角色。通过克隆原型角色对象,可以快速生成新的角色对象,减少了创建角色的开销。
  • 在数据库应用中,经常需要对数据库记录进行增删改查操作。使用原型设计模式,可以通过复制已有的数据库记录对象来创建新的记录对象,然后对新对象进行修改或插入操作,从而实现数据的快速操作和灵活性。
  • 在图形编辑器中,用户可以通过复制和粘贴操作来创建新的图形对象。这时可以使用原型设计模式,将已有的图形对象作为原型,在需要时通过克隆操作创建新的图形对象,避免了重新构造复杂的图形对象。
  • 在操作系统中,进程的创建和销毁是一个频繁且耗资源的操作。使用原型设计模式,可以通过克隆已有的进程对象来创建新的进程对象,提高了进程创建的效率
  • 原型设计模式可以与对象池模式结合使用,实现对象的缓存和复用。通过创建一组原型对象,并在需要时通过克隆操作获取对象,可以避免频繁地创建和销毁对象,提高系统的性能

一、原型模式的简单实现

下面例举个示例,父类实现 ICloneable 接口的 Clone() 方法:

// 父类:图形类
abstract class Shape : ICloneable // 实现接口 ICloneable 中的方法 Clone
{
    protected string type;
    public abstract void Draw();
    public object Clone()
    {
        return this.MemberwiseClone(); // 创建当前对象的浅拷贝,两个引用指向同一个对象
        // 注意:
        // 浅拷贝就相当于给引用对象又起了另外一个名字,小黄和修勾勾都指的是这一只小狗;
        // 深拷贝就是用克隆技术,把小黄复刻了一个长得一模一样的小黄二号,名字不同的同时指的对象也不同。
    }
}
// 圆形类,继承图形类
class Circle : Shape
{
    public Circle()
    {
        type = "Circle";
    }
    public override void Draw()
    {
        Console.WriteLine("Drawing a circle");
    }
}
// 矩形类,也继承图形类
class Rectangle : Shape
{
    public Rectangle()
    {
        type = "Rectangle";
    }
    public override void Draw()
    {
        Console.WriteLine("Drawing a rectangle");
    }
}
class Program
{
    static void Main(string[] args)
    {
        Circle circle = new Circle(); // 创建一个圆形对象
        Circle clonedCircle = (Circle)circle.Clone(); // 克隆圆形对象(复制了对象的引用)
        // circle 和 clonedCircle 两个引用,指向同一个对象
        clonedCircle.Draw();
        
        Rectangle rectangle = new Rectangle(); // 创建一个矩形对象        
        Rectangle clonedRectangle = (Rectangle)rectangle.Clone(); // 克隆矩形对象
        // rectangle 和 clonedRectangle 两个引用,指向同一个对象
        clonedRectangle.Draw();
        Console.ReadKey();
    }
}

如下输出结果,调用克隆对象的 Draw() 得出:

  

二、结构

根据上一章节的示例代码,简单画一个 UML 图:

Shape:原型抽象,声明一个抽象类,实现 ICloneable 接口的 Clone() 方法,使得本抽象类可以被克隆。

Circle、Rectangle:原型,继承抽象类 Shape,实现自身可被克隆的性质。

Client:创建可被克隆的原型,并通过 Clone() 方法复制原型。

三、原型模式在 .Net 中的实际应用

例如在数据库连接管理的应用。

在数据库应用程序中,连接到数据库可能是一个耗时且资源密集的操作。为了避免每次都重新创建连接,可以使用原型设计模式来克隆现有的连接对象。

public class DbConnection : ICloneable
{
    public string ConnectionString { get; set; }
    // ...
    
    public object Clone()
    {
        return this.MemberwiseClone();
    }
}
// 使用示例:
DbConnection originalConnection = new DbConnection { ConnectionString = "..." };
DbConnection clonedConnection = (DbConnection)originalConnection.Clone();

四、相关模式

Prorotype 和 AbstractFactory 模式在某些方面是互相竞争的。但是它们也可以一起使用,AbstractFactory 可以存储一个被克隆对象的原型集合,并且返回产品对象。

  • 原型设计模式的主要目的是通过克隆现有对象来创建新对象,以避免重复创建相似的对象。它适用于需要动态生成对象的情况,并且能够在运行时选择要克隆的对象。
  • 抽象工厂模式的主要目的是提供一个接口来创建一系列相关或依赖对象的家族,而无需指定具体的类。它适用于需要创建一组相关对象的情况,并且能够在运行时切换整个对象家族。

大量使用 Composite(组合) 和 Decorator(装饰) 模式的设计,通常也可以用到 Prototype 模式。

标签:克隆,示例,C#,创建,Clone,对象,原型,设计模式
From: https://www.cnblogs.com/hnzhengfy/p/SJMSLL_Prototype.html

相关文章

  • C#的winform如何嵌套另一个exe程序
    这篇文章主要介绍了C#的winform如何嵌套另一个exe程序问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教 −目录C#winform嵌套另一个exe程序第一种第二种总结C#winform嵌套另一个exe程序一共有二种方法,也不知道作者从哪里复制来的,......
  • AndroidStudio SurfaceView SurfaceHolder关系
    电视机就像是屏幕,而SurfaceView则是你要在屏幕上显示的内容。然而,你不能直接在电视机上直接绘制内容,就像你不能直接在SurfaceView上绘制内容一样。这就是SurfaceHolder登场的地方。SurfaceHolder就像是遥控器,它是控制你如何在电视屏幕上显示内容的工具。你通过遥控器来切......
  • idea导入新springboot项目时 如何进行configure相关的配置 启动项目
    idea导入springboot项目运行教程前置要求①具备Java环境,并且可以通过Maven进行安装项目依赖;②具备IntelliJIDEA工具,推荐专业版,社区版也不影响;③具备Mysql5.7或以上版本数据库;④具备Navicat数据库可视化管理工具;⑤推荐使用GoogleChrome、Firefox浏览器idea导入项目的运行教......
  • IfcDayInMonthNumber
    IfcDayInMonthNumber类型定义IfcDayInMonthNumber是一个整数,用于定义指定日期在一个月中的位置。 类型:整数 IFC1.5.1中的新型。IFC4添加规则ValidRange的位置 FormalPropositionsRuleDescriptionValidRangeThevalidrangeforpositioningadayinamonth......
  • 笔记整理--C语言--数组指针和指针数组的区别 - hongcha_717 - 博客园——转载
    【转载】:原文http://www.cnblogs.com/hongcha717/archive/2010/10/24/1859780.html数组指针和指针数组的区别数组指针(也称行指针)定义int(*p)[n];()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个......
  • c# - 如何在圆角 WPF 窗体中创建圆角矩形?
    我正在WPF中创建一个应用程序,我想要圆角。收到。现在窗体是无边框的,我正在尝试创建一个圆角矩形并将其放在顶部,使其看起来像Windows应用程序的顶部栏。我做不到。这是我的代码:<BorderCornerRadius="50,0,50,0"BorderBrush="Black"BorderThickness="2"Background="......
  • C# SECS/GEM协议
    一、概念  SECS/GEMI标准(制造设备通信和控制的通用模型)指的是一组用于管理制造设备和工厂主机系统之间通信的半导体行业标准,由国际半导体协议SEMI发起并维护。GEM基于其他较低级别的标准,如下:图片后补协议名称用途SECS-I定义RS-232通信的标准(报文)HSMS定义TCP/......
  • 安森美 IDE(基于Eclipse)报头文件缺少的解决方法
    安森美IDE(基于Eclipse)报头文件缺少,但是能正常跳转到头文件在这里面将路径包含进来,建议两个都添加一次  在项目上点击右键,然后点击Index下的Rebuild重建 ......
  • SpringCloud 微服务的协调者
    一、什么是SpringCloud1、功能:配置管理、服务注册、服务发现、断路器、智能路由、负载均衡、服务间调用、微代理、一次性令牌、思维导图模板、全局锁、领导选举、分布式消息、分布式会话、集群状态2、SpringCloud与SpringBoot的关系SpringBoot是构建SpringCloud架......
  • MySQL客户端工具 phpMyAdmin MySQL Workbench HeidiSQL Sequel Pro DBeaver
    MySQL是一种流行的关系型数据库管理系统,它被广泛用于Web应用程序和企业级应用程序的开发中。目前,市面上有不少好用的MySQL客户端工具,如Navicat,SQLyog等。但这些产品虽然功能强大,却都是收费的,而且费用还不低。幸运的是,收费产品并不是你的唯一选择,目前也有不少开源的工具。如果你不想......