23设计模式 创建型
1 单例 SinglePattern 整个程序只有一个实力 保证程序中只有一个实例被创建
(线程池,数据库连接池 ,配置文件对象,Ioc容器实例 等程序中只需要一个实例的过程,单例是常驻内存)
2 工厂方法 Method Factory
3 抽象工厂 Abstrac Factory
4 建造者 Builder 是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示,创建者模式隐藏了复杂对象的创建过程。
5 原型 Protype
6 简单工厂 simple Factory
单例 SinglePattern
懒汉式 private Singleton() { long lResult = 0; for (int i = 0; i < 10000000; i++) { lResult += i; } Thread.Sleep(2000); Console.WriteLine($"{this.GetType().Name}被构造一次 {Thread.CurrentThread.ManagedThreadId}"); } private static Singleton _Singleton = null; private static readonly object Singleton_Lock = new object(); public static Singleton CreateInstance() { if (_Singleton == null)//为了提升性能,对象初始化之后能够并发 { lock (Singleton_Lock)//保证任意时刻只有一个线程可以进入 { if (_Singleton == null)//里面的也不能去掉,因为在最开始并发时需要控制的,仅仅用于第一次初始化时的并发判断,防止重复初始化 { _Singleton = new Singleton(); } } } return _Singleton; }
饿汉式 private SingletonSecond() { long lResult = 0; for (int i = 0; i < 10000000; i++) { lResult += i; } Thread.Sleep(2000); Console.WriteLine($"{this.GetType().Name}被构造一次 {Thread.CurrentThread.ManagedThreadId}"); } ////// 由CLR调用,且只调用一次,会在程序第一次使用该类型之前 /// static SingletonSecond() { _SingletonSecond = new SingletonSecond(); } private static SingletonSecond _SingletonSecond = null; public static SingletonSecond CreateInstance() { return _SingletonSecond; }
饿汉式 private SingletonThird() { long lResult = 0; for (int i = 0; i < 10000000; i++) { lResult += i; } Thread.Sleep(2000); Console.WriteLine($"{this.GetType().Name}被构造一次 {Thread.CurrentThread.ManagedThreadId}"); } ////// 静态字段也是由CLR保障的,在程序第一次使用该类型之前,完成初始化,且只初始化一次 /// /// 静态字段 1先执行 /// 静态构造函数 2后执行 /// 谁先执行 /// private static SingletonThird _SingletonThird = new SingletonThird(); public static SingletonThird CreateInstance() { return _SingletonThird; }
public static Donoting()
{
// 调用 Donoting() 的静态方法
// 会先初始化静态字段->静态构造函数-> 这样迫不及待的调用叫饿汉
}
//类里面各个元素的初始化顺序 //静态字段1--静态构造函数2--普通属性---构造函数3--普通字段
Program program = new Program(); // //开辟内存空间 a // //执行构造函数 b // //引用地址绑定给变量 c //克隆就少了第二步
原型 SingleProtope
//内存复制---浅克隆 内存克隆开辟新的空间指向栈中同一个地方 ,栈中的并没有改变
//解决了单例对象覆盖问题,通过内存拷贝
//单例的话会相互覆盖 新的覆盖旧的
//1 一般情况下,我们构造函数也不折腾。。。
//2 new习惯了,习惯也是一种力量,
//3 原型模式也有个常驻内存的东西
//4 IOC不能玩,构造函数的初始化也失效了
//5克隆其实就是绕开内存
private SingletonPrototype()浅克隆 { long lResult = 0; for (int i = 0; i < 10000000; i++) { lResult += i; } Thread.Sleep(2000); Console.WriteLine($"{this.GetType().Name}被构造一次 {Thread.CurrentThread.ManagedThreadId}"); } private static SingletonPrototype _SingletonPrototype = new SingletonPrototype(); ////// 原型模式 /// ///public static SingletonPrototype CreateInstance() { SingletonPrototype instance = (SingletonPrototype)_SingletonPrototype.MemberwiseClone();
return instance;
}
{ SingletonPrototype singleton1 = SingletonPrototype.CreateInstance(); SingletonPrototype singleton2 = SingletonPrototype.CreateInstance(); singleton1.Id = 123; singleton1.Name = "金辰"; singleton2.Id = 234; singleton2.Name = "大浪"; //代码这样写,会不会有什么问题,或者出现什么意料之外的事儿? //覆盖--因为单例,是同一个对象,操作就互相覆盖了,以后面的为准 //单例可以避免重复初始化对象(构造函数浪费时间)---但是对象覆盖了--- //有没有办法兼得? }
// 深克隆
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(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) { return Derializable (Serializable(t)); }
创建对象的方法
1new
2克隆
3反序列化
4反射