创建型模式 - 原型模式Prototype

孩子生来没娘的NT审核机制,又开始说我涉及到广告了,我涉及到什么广告了?我接着发。

学习而来,代码是自己敲的。也有些自己的理解在里边,有问题希望大家指出。

所属:创建型模式 

原型模式 一般会和 工场模式 组合。 

原型模式的定义与特点

        原型(Prototype)模式的定义如下:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效,根本无须知道对象创建的细节。例如,Windows 操作系统的安装通常较耗时,如果复制就快了很多。在生活中复制的例子非常多,这里不一一列举了。  

原型模式的优点:

  • 可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份,并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作

原型模式的缺点:

  • 需要为每一个类都配置一个 clone 方法
  • clone 方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违背了开闭原则。
  • 当实现深克隆时,需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。因此,深克隆、浅克隆需要运用得当。

原型模式的结构与实现

C#提供了对象的 MemberwiseClone() 方法

1. 模式的结构

原型模式包含以下主要角色。

  1. 抽象原型类:规定了具体原型对象必须实现的接口。
  2. 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
  3. 访问类:使用具体原型类中的 clone() 方法来复制新的对象。

其结构图如图 1 所示。

 原型模式的克隆分为浅克隆和深克隆。

  • 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
  • 深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。
  • C#提供的MemberwiseClone()方法为浅克隆

代码 

using DesignPattern.PrototypePattern;
using System;

namespace DesignPattern
{
    internal class Program
    {
        static void Main(string[] args)
        {
            PrototypeHelper();
        }

        #region Pattern - Prototype
        static void PrototypeHelper()
        {
            ObjectProtoType _proto0 = new ObjectProtoType("Name_0");
            ObjectProtoType _proto1 = (ObjectProtoType)_proto0.Clone();
            ObjectProtoType _proto2 = (ObjectProtoType)_proto0.Copy();

            Console.WriteLine("最开始 _proto0.Clone出_proto1     _proto0.Copy出_proto2         _proto0 的属行和字段值:");
            Console.WriteLine($"Name = {_proto0.Name}    Number = {_proto0.Number}    aA.name = {_proto0.aA.name}");
            Console.WriteLine();


            _proto1.SetName("SetName_1");
            _proto2.SetNumber(2321312);
            _proto0.aA.name = "AAAAA";

            Console.WriteLine("_proto1 修改了 Name 为:SetName_1");
            Console.WriteLine("_proto2 修改了 Number 为:" + 2321312);
            Console.WriteLine("_proto0 修改了 aA.name 为:AAAAA");

            Console.WriteLine();
            Console.WriteLine("结束时 全部 _proto 的属行和字段值:");
            Console.WriteLine($"_proto0.Name = {_proto0.Name}\t\t\t_proto0.Number = {_proto0.Number}\t\t\t _proto0.aA.name = {_proto0.aA.name}");
            Console.WriteLine($"_proto1.Name = {_proto1.Name}\t\t_proto1.Number = {_proto1.Number}\t\t\t _proto1.aA.name = {_proto1.aA.name}");
            Console.WriteLine($"_proto2.Name = {_proto2.Name}\t\t\t_proto2.Number = {_proto2.Number}\t\t _proto2.aA.name = {_proto2.aA.name}");
            Console.ReadLine();
        }
        #endregion
    }
}

//======================================================================================

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace DesignPattern.PrototypePattern
{
    public interface IProtoType
    {
        object Copy();
        object Clone();
    }

    [Serializable]
    public class ProtoType : IProtoType
    {
        public object Clone() => MemberwiseClone();

        public object Copy()
        {
            using (var ms = new MemoryStream())
            {
                BinaryFormatter binaryFormatte = new BinaryFormatter();
                binaryFormatte.Serialize(ms, this);
                ms.Seek(0, SeekOrigin.Begin);
                return binaryFormatte.Deserialize(ms);
            }
        }
    }

    [Serializable]
    public class ObjectProtoType : ProtoType
    {
        public ObjectProtoType(string name)
        {
            Name = name;
        }
        public string Name;
        public int Number = 0;
        public AA aA = new AA("-----------aaa");


        public void SetName(string name)
        {
            Name = name;
        }
        public void SetNumber(int number)
        {
            this.Number = number;
        }
    }

    [Serializable]
    public class AA
    {
        public string name;
        public AA(string name)
        {
            this.name = name;
        }
    }
}


希望大家:点赞,留言,关注咯~    

😘😘😘😘

唠家常

  • Xiaohei.Wang(Wenhao)的今日分享结束啦,小伙伴们你们get到了么,你们有没有更好的办法呢,可以评论区留言分享,也可以加我的QQ:841298494 (记得备注),大家一起进步

今日推荐

GoF 的 23 种设计模式的分类和功能这是Xiaohei自己总结的内容,会持续更新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青衫磊落长歌行

觉得小黑这篇文章不赖,打赏哟~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值