来自: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