ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【23种GOF设计模式】C#代码完整案例详解--原型模式

2022-01-28 22:05:02  阅读:157  来源: 互联网

标签:Console Name 23 C# System WriteLine using 设计模式 public


来自:CCNetCore社区,一个关注.Netcore领域的社区团队。

原型模式PrototypePattern

原型模式PrototypePattern 创建型设计模式

用于对象的创建,通常用于单例模式中。
由于单例模式的对象始终为1个,又要用到单例模式又想每次调用有不一样的结果,可以使用原型模式。
添加一个创建实例的方法即可。
可通过内存复制或者with关键字进行浅拷贝
可通过序列化再反序列化进行深度拷贝

要区分一下值类型与引用类型。栈中存储变量,堆存储值。
string是一个特殊的引用对象,每次赋值时都会创建新的实例。

例如:单例模式中又想每次调用有不同结果,可使用原型模式。

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PrototypePattern
{
   /// <summary>
   /// 1 单例模式/原型模式/享元模式
   /// 2 浅克隆VS深克隆,原型模式的应用
   /// 3 C#内存分配机制详析
   /// 
   /// 设计模式:面向对象语言开发过程中,遇到种种场景和问题,提出的解决方案和思路,沉淀下来
   ///           ----设计模式 套路,解决问题的套路,站在前辈的肩膀上
   /// 创建型设计模式--关注对象的创建--new()--三大工厂+建造者+单例+原型
   /// 即使是一个简单的对象复用,都有很多招数--
   /// 
   /// 结构型设计模式
   /// 行为型设计模式
   /// 
   /// C#内存分配机制
   /// 
   /// 原型模式也就是用利用对象copy,快速获取对象---需要大量新对象的时候
   /// 
   /// 
   /// </summary>
   class Program
   {
       static void Main(string[] args)
       {
           try
           {
               Console.WriteLine("欢迎来到.net高级班公开课之设计模式特训,今天是Eleven老师为大家带来的原型模式Prototype");
               {
                   //Console.WriteLine("***************Common**************");
                   ////对象复用---循环的就最简单了---不同的方法/类/线程/类库--重用对象
                   //Student student = new Student()
                   //{
                   //    Id = 1121,
                   //    Name = "馒头哥"
                   //};
                   //for (int i = 0; i < 5; i++)
                   //{
                   //    //Student student = new Student()
                   //    //{
                   //    //    Id = 1121,
                   //    //    Name = "馒头哥"
                   //    //};
                   //    student.Study();
                   //}
               }
               {
                   //Console.WriteLine("***************Singleton**************");
                   ////挺熟悉单例的刷个1  不太熟悉刷个2
                   ////单例模式:保证整个进程中,该对象只有一个实例
                   //for (int i = 0; i < 5; i++)
                   //{
                   //    StudentSingleton student = StudentSingleton.CreateInstance();
                   //    student.Study();
                   //}
                   ////对单例不太熟悉的,建议加一下课堂的助教老师,获取单例课程的视频代码
               }
               {
                   //Console.WriteLine("***************Singleton**************");
                   //StudentSingleton student1 = StudentSingleton.CreateInstance();
                   //StudentSingleton student2 = StudentSingleton.CreateInstance();
                   //student1.Id = 234;
                   //student1.Name = "CodeMan";

                   //student2.Id = 345;
                   //student2.Name = "左耳听风";

                   //student1.Study();
                   //student2.Study();
                   ////单例---整个进程只有一个实例--能出现2个学生?不可能!---后面会覆盖前面的
               }
               {
                   //单例可以对象复用---但是会出现覆盖
                   //能不能不覆盖,但是性能也高?
                   //Console.WriteLine("***************Prototype**************");
                   //for (int i = 0; i < 5; i++)
                   //{
                   //    StudentPrototype student = StudentPrototype.CreateInstance();
                   //    student.Study();
                   //}
               }
               {
                   Console.WriteLine("***************Prototype**************");
                   StudentPrototype student1 = StudentPrototype.CreateInstance();
                   StudentPrototype student2 = StudentPrototype.CreateInstance();
                   StudentPrototype student3 = StudentPrototype.CreateInstance();
                   student1.Id = 234;
                   student1.Name = "CodeMan";
                   student1.Class.ClassId = 2;
                   student1.Class.ClassName = "架构班";
                   //因为string类型的 ="CodeMan" 等同于 new String("CodeMan"); 开辟新的空间,不影响之前的-----实际上string是不可修改的----

                   student2.Id = 345;
                   student2.Name = "左耳听风";
                   student2.Class.ClassId = 3;
                   student2.Class.ClassName = "全栈班";

                   student3.Id = 456;
                   student3.Name = "NULL";
                   student3.Class = new Class()
                   {
                       ClassId = 4,
                       ClassName = "实战班"
                   };//换了个引用
                   student1.Study();
                   student2.Study();
                   student3.Study();
                   //student1的 classid   student2 student3   234   444 或者其他
                   //C#内存分配----334
               }
               {
                   //C#内存分  进程堆(进程唯一)-----线程栈(每个线程一个)
                   //引用类型在堆里,值类型在栈里---变量都在栈里
                   //引用类型对象里面的值类型---student1.Id 堆还是栈?---在堆里
                   //值类型里面的引用类型---Custom.Name 堆还是栈?----在堆里(任何引用类型的值都在堆里)
               }
           }
           catch (Exception ex)
           {
               Console.WriteLine(ex.Message);
           }
           Console.Read();
       }

       private static void Show()
       {
           Console.WriteLine("***************Show**************");
           for (int i = 0; i < 5; i++)
           {
               Student student = new Student()
               {
                   Id = 1121,
                   Name = "馒头哥"
               };
               student.Study();
           }
       }
   }

   public struct Custom
   {
       public string Name;
   }
}

Student.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace PrototypePattern
{
   /// <summary>
   /// 普通类
   /// 创建的时候很耗时  耗资源等
   /// </summary>
   public class Student
   {
       public Student()
       {
           Thread.Sleep(2000);
           long lResult = 0;
           for (int i = 0; i < 1000000; i++)
           {
               lResult += i;
           }
           Console.WriteLine("{0}被构造..", this.GetType().Name);
       }

       public int Id { get; set; }
       public string Name { get; set; }

       public void Study()
       {
           Console.WriteLine("{0}在学习.net高级班公开课之设计模式特训", this.Name);
       }

   }
}

StudentPrototype.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace PrototypePattern
{
   /// <summary>
   /// 普通类
   /// 创建的时候很耗时  耗资源等
   /// </summary>
   public class Student
   {
       public Student()
       {
           Thread.Sleep(2000);
           long lResult = 0;
           for (int i = 0; i < 1000000; i++)
           {
               lResult += i;
           }
           Console.WriteLine("{0}被构造..", this.GetType().Name);
       }

       public int Id { get; set; }
       public string Name { get; set; }

       public void Study()
       {
           Console.WriteLine("{0}在学习.net高级班公开课之设计模式特训", this.Name);
       }

   }
}
StudentSingleton.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace PrototypePattern
{
   /// <summary>
   /// 单例类
   /// </summary>
   public class StudentSingleton
   {
       /// <summary>
       /// 1 构造函数私有化--避免随意构造
       /// </summary>
       private StudentSingleton()
       {
           Thread.Sleep(2000);
           long lResult = 0;
           for (int i = 0; i < 1000000; i++)
           {
               lResult += i;
           }
           Console.WriteLine("{0}被构造..", this.GetType().Name);
       }
       /// <summary>
       /// 3 私有的静态字段--内存唯一,不会释放,且在第一次使用这个类被初始化且只初始化一次
       /// </summary>
       private static StudentSingleton _Student = new StudentSingleton()
       {
           Id = 123,
           Name = "ywa"
       };
       /// <summary>
       /// 2 公开的静态方法来提供实例
       /// </summary>
       /// <returns></returns>
       public static StudentSingleton CreateInstance()
       {
           return _Student;
       }


       public int Id { get; set; }
       public string Name { get; set; }

       public void Study()
       {
           Console.WriteLine("{0}在学习.net高级班公开课之设计模式特训", this.Name);
       }

   }
}

SerializeHelper.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace PrototypePattern
{
   public class SerializeHelper
   {
       public static string Serializable(object target)
       {
           using (MemoryStream stream = new MemoryStream())
           {
               new BinaryFormatter().Serialize(stream, target);

               return Convert.ToBase64String(stream.ToArray());
           }
       }
       public static T Derializable<T>(string target)
       {
           byte[] targetArray = Convert.FromBase64String(target);

           using (MemoryStream stream = new MemoryStream(targetArray))
           {
               return (T)(new BinaryFormatter().Deserialize(stream));
           }
       }
       public static T DeepClone<T>(T t)
       {
           return Derializable<T>(Serializable(t));
       }
   }
}

最后,想了解更多,可加入CCNetCore社区,橙子带你走上.netcore学习之路。
你可以免费获取到:

  • 设计模式
  • 面试八股文
  • 问题答疑
  • 闲聊茶馆
  • Asp.Netcore图文源码解读
  • 第一代软件架构单体应用相关技术
  • 第二代软件架构分布式应用相关技术
  • 第三代软件架构微服务应用相关技术
  • 第四代软件架构网格服务应用相关技术

站点网址:ccnetcore.com

标签:Console,Name,23,C#,System,WriteLine,using,设计模式,public
来源: https://www.cnblogs.com/ccnetcore/p/15853892.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有