• 23种设计模式之原型模式(Prototype Pattern)


    原型模式

    使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象

    分析:

    孙悟空:根据自己的形状复制(克隆)出多个身外身
    软件开发:通过复制一个原型对象得到多个与原型对象一模一样的新对象
     
    工作原理:将一个原型对象传给要发动创建的对象(即客户端对象),这个要发动创建的对象通过请求原型对象复制自己来实现创建过程
    创建新对象(也称为克隆对象)的工厂就是原型类自身,工厂方由负责复制原型对象的克隆方法来实现
    通过克隆方法所创建的对象是全新的对象,它们在内存中拥有新的地址,每一个克隆对象都是独立
    通过不同的方式对克隆对象进行修改以后,可以得到一系列相似但不完全相同的对象
     
    原型模式的结构
    原型模式包含以下3个角色:
    •Prototype(抽象原型类)
    •ConcretePrototype(具体原型类)
    •Client(客户类)
     
    浅克隆与深克隆
    浅克隆(Shallow Clone)当原型对象被复制时,只复制它本身和其中包含的值类型的成员变量,而引用类型的成员变量并没有复制
    深克隆(Deep Clone)除了对象本身被复制外,对象所包含的所有成员变量也将被复制
     1     /// <summary>
     2     /// 原型模式:单例的基础上升级了一下,把对象从内存层面复制了一下,然后返回
     3     ///    是个新对象,但是又不是new出来的
     4     /// </summary>
     5     [Serializable] 
     6     public class Prototype
     7     {
     8         /// <summary>
     9         /// 构造函数耗时耗资源
    10         /// </summary>
    11         private Prototype()
    12         {
    13             long lResult = 0;
    14             for (int i = 0; i < 10000000; i++)
    15             {
    16                 lResult += i;
    17             }
    18             Thread.Sleep(2000);
    19             Console.WriteLine("{0}被构造一次", this.GetType().Name);
    20         }
    21         /// <summary>
    22         /// 3 全局唯一静态  重用这个变量
    23         /// </summary>
    24         private static volatile Prototype _Prototype = new Prototype()
    25         {
    26             CurrentEmployee = "admin",
    27             Member = new Member { Id=1,Name="aaa"}
    28         };
    29         /// <summary>
    30         /// 2 公开的静态方法提供对象实例
    31         /// </summary>
    32         /// <returns></returns>
    33         public static Prototype CreateInstance()
    34         {
    35             Prototype prototype = (Prototype)_Prototype.MemberwiseClone();
    36             return prototype;
    37         }
    38         public static Prototype DeepClone()
    39         {
    40             Prototype prototype = JsonConvert.DeserializeObject<Prototype>(JsonConvert.SerializeObject(_Prototype));
    41             return prototype;
    42         }
    43         public Member Member { get; set; }
    44         public string CurrentEmployee { get; set; }
    45     }
    46     [Serializable] 
    47     public class Member
    48     {
    49         public int Id { get; set; }
    50         public string Name { get; set; }
    51     }
    View Code

    前端调用

     1                 {//浅拷贝
     2                     Prototype prototype1 = Prototype.CreateInstance();
     3                     Prototype prototype2 = Prototype.CreateInstance();
     4                     prototype1.CurrentEmployee = "prototype1";
     5                     prototype1.Member.Id = 2;
     6                     prototype1.Member.Name = "bbb";
     7                     prototype2.CurrentEmployee = "prototype2";
     8                     prototype2.Member.Id = 3;
     9                     prototype2.Member.Name = "ccc";
    10                     Console.WriteLine(prototype1.CurrentEmployee);
    11                     Console.WriteLine(prototype1.Member.Id);
    12                     Console.WriteLine(prototype1.Member.Name);
    13                     Console.WriteLine(prototype2.CurrentEmployee);
    14                     Console.WriteLine(prototype2.Member.Id);
    15                     Console.WriteLine(prototype2.Member.Name);
    16                 }
    17                 {//深拷贝
    18                     Prototype prototype1 = Prototype.DeepClone();
    19                     Prototype prototype2 = Prototype.DeepClone();
    20                     prototype1.CurrentEmployee = "prototype1";
    21                     prototype1.Member.Id = 2;
    22                     prototype1.Member.Name = "bbb";
    23                     prototype2.CurrentEmployee = "prototype2";
    24                     prototype2.Member.Id = 3;
    25                     prototype2.Member.Name = "ccc";
    26                     Console.WriteLine(prototype1.CurrentEmployee);
    27                     Console.WriteLine(prototype1.Member.Id);
    28                     Console.WriteLine(prototype1.Member.Name);
    29                     Console.WriteLine(prototype2.CurrentEmployee);
    30                     Console.WriteLine(prototype2.Member.Id);
    31                     Console.WriteLine(prototype2.Member.Name);
    32                 }
    View Code

    执行结果

    深度拷贝就是利用序列化与反序列化创建对象,这种方法好像也走构造函数,那么还不如直接new 就失去了原型模式的意义了

    本文参考文档:https://www.cnblogs.com/genesis/p/6097528.html

  • 相关阅读:
    Codeforces 177G2 Fibonacci Strings KMP 矩阵
    Codeforces Gym100187C Very Spacious Office 贪心 堆
    Codeforces 980F Cactus to Tree 仙人掌 Tarjan 树形dp 单调队列
    AtCoder SoundHound Inc. Programming Contest 2018 E + Graph (soundhound2018_summer_qual_e)
    BZOJ3622 已经没有什么好害怕的了 动态规划 容斥原理 组合数学
    NOIP2016提高组Day1T2 天天爱跑步 树链剖分 LCA 倍增 差分
    Codeforces 555C Case of Chocolate 其他
    NOIP2017提高组Day2T3 列队 洛谷P3960 线段树
    NOIP2017提高组Day2T2 宝藏 洛谷P3959 状压dp
    NOIP2017提高组Day1T3 逛公园 洛谷P3953 Tarjan 强连通缩点 SPFA 动态规划 最短路 拓扑序
  • 原文地址:https://www.cnblogs.com/Dewumu/p/11435195.html
Copyright © 2020-2023  润新知