重庆放心seo整站优化,企业网络营销方案设计,响应式网页设计名词解释,天水网站建设公司排名前言 之前看到朋友采用继承的方式来实现单例模式#xff0c;觉得很厉害#xff0c;随后自己去探索了一番#xff0c;以前实现单例模式都是把代码内联到具体的类中#xff0c;这使得工程中每次需要使用单例模式时#xff0c;都采用拷贝的方式#xff0c;增加了很多冗余代码…前言 之前看到朋友采用继承的方式来实现单例模式觉得很厉害随后自己去探索了一番以前实现单例模式都是把代码内联到具体的类中这使得工程中每次需要使用单例模式时都采用拷贝的方式增加了很多冗余代码并且难以规范单例的统一标准使得代码不方便扩展和管理。这次探索找到了一种实现方式先记录下来后续如果有其它方式再发表系列文章示例代码为C#。 代码
v1.0版本
using System;/// summary
/// 单例模式基类
/// /summary
/// typeparam nameT单例类型/typeparam
public abstract class SingletonT
where T : class, new()
{public static T instance _instance.Value;static bool _unlock;static readonly LazyT _instance new LazyT(() {_unlock true;return new T();});protected Singleton(){if (!_unlock)throw new InvalidOperationException(Singleton:The ctor is proxied by singleton and cannot be called from outside.);_unlock false;}
}
v1.1
using System;/// summary
/// 单例模式基类
/// /summary
/// typeparam nameT单例类型/typeparam
public abstract class SingletonT
where T : class, new()
{public static T instance _instance.Value;static bool _unlock;static readonly LazyT _instance new LazyT(Create);static T Create(){_unlock true;T item new T();_unlock false;return item;}protected Singleton(){if (!_unlock)throw new InvalidOperationException(Singleton:The ctor is proxied by singleton and cannot be called from outside.);}
}
测试
单例基类
using System;/// summary
/// 单例模式基类
/// 版本1.0
/// /summary
/// typeparam nameT单例类型/typeparam
// public abstract class SingletonWithTestT
// where T : class, new()
// {
// public static T instance _instance.Value;
// static bool _unlock;
// static readonly LazyT _instance new LazyT(()
// {
// _unlock true;
// return new T();
// });// protected SingletonWithTest()
// {
// if (!_unlock)
// {
// // throw new InvalidOperationException(Singleton:The ctor is proxied by singleton and cannot be called from outside.);
// Console.WriteLine($Singleton({GetHashCode()}):The ctor is proxied by singleton and cannot be called from outside.);
// return;
// }
// _unlock false;
// Console.WriteLine(*************************);
// }
// }/// summary
/// 单例模式基类
/// 版本1.1
/// /summary
/// typeparam nameT单例类型/typeparam
public abstract class SingletonWithTestT
where T : class, new()
{public static T instance _instance.Value;static bool _unlock;static readonly LazyT _instance new LazyT(Create);static T Create(){_unlock true;T item new T();_unlock false;return item;}protected SingletonWithTest(){if (!_unlock){// throw new InvalidOperationException(Singleton:The ctor is proxied by singleton and cannot be called from outside.);Console.WriteLine($Singleton({GetHashCode()}):The ctor is proxied by singleton and cannot be called from outside.);return;}Console.WriteLine(*************************);}
}
单例继承类
public class TestA : SingletonWithTestTestA
{public readonly string key;public TestA() { key Default A; }public TestA(string key) { this.key key; }
}public class TestB : SingletonWithTestTestB
{public readonly string key;public TestB() { key Default B; }public TestB(string key) { this.key key; }
}public class TestC : SingletonWithTestTestC
{public readonly string key;public TestC() { key Default C; }public TestC(string key) { this.key key; }
}public class TestD : SingletonWithTestTestD
{public readonly string key;public TestD() { key Default D; }public TestD(string key) { this.key key; }
}public class TestE : SingletonWithTestTestE
{public readonly string key;public TestE() { key Default E; }public TestE(string key) { this.key key; }
}public class TestF : SingletonWithTestTestF
{public readonly string key;public TestF() { key Default F; }public TestF(string key) { this.key key; }
}
测试代码
// ********************************* 创建实例测试通过 ********************************* // 直接创建实例测试通过
// TestA a new TestA(); // 无法通过 new 无参ctor 创建实例
// TestA a1 new TestA(A1); // 无法通过 new 有参ctor 创建实例
// TestA a2 Activator.CreateInstanceTestA(); // 无法通过 Activator 创建实例
// TestA? a2 Activator.CreateInstance(typeof(TestA), A1) as TestA; // 无法通过 Activator 创建实例// ********************************* 线程安全测试通过 *********************************Thread t1, t2, t3, t4, t5, t6;// 打印同一单例的 HashCode 测试通过
t1 new Thread(() Console.WriteLine(Thread1: TestA.instance.GetHashCode()));
t2 new Thread(() Console.WriteLine(Thread2: TestA.instance.GetHashCode()));
t3 new Thread(() Console.WriteLine(Thread3: TestA.instance.GetHashCode()));
t4 new Thread(() Console.WriteLine(Thread4: TestA.instance.GetHashCode()));
t5 new Thread(() Console.WriteLine(Thread5: TestA.instance.GetHashCode()));
t6 new Thread(() Console.WriteLine(Thread6: TestA.instance.GetHashCode()));// 使用单例的同时直接创建该单例类型实例测试通过
// t1 new Thread(() Console.WriteLine(Thread1: TestA.instance.GetHashCode()));
// t2 new Thread(() Console.WriteLine(Thread2: new TestA().GetHashCode()));
// t3 new Thread(() Console.WriteLine(Thread3: new TestA().GetHashCode()));
// t4 new Thread(() Console.WriteLine(Thread4: new TestA().GetHashCode()));
// t5 new Thread(() Console.WriteLine(Thread5: new TestA().GetHashCode()));
// t6 new Thread(() Console.WriteLine(Thread6: new TestA().GetHashCode()));// 同时使用不同单例的测试通过
// t1 new Thread(() Console.WriteLine(Thread1: TestA.instance.GetHashCode()));
// t2 new Thread(() Console.WriteLine(Thread2: TestB.instance.GetHashCode()));
// t3 new Thread(() Console.WriteLine(Thread3: TestC.instance.GetHashCode()));
// t4 new Thread(() Console.WriteLine(Thread4: TestD.instance.GetHashCode()));
// t5 new Thread(() Console.WriteLine(Thread5: TestE.instance.GetHashCode()));
// t6 new Thread(() Console.WriteLine(Thread6: TestF.instance.GetHashCode()));// 使用单例的同时创建其它单例类型的实例测试通过
// t1 new Thread(() Console.WriteLine(Thread1: TestA.instance.GetHashCode()));
// t2 new Thread(() Console.WriteLine(Thread2: new TestB().GetHashCode()));
// t3 new Thread(() Console.WriteLine(Thread3: new TestC().GetHashCode()));
// t4 new Thread(() Console.WriteLine(Thread4: new TestD().GetHashCode()));
// t5 new Thread(() Console.WriteLine(Thread5: new TestE().GetHashCode()));
// t6 new Thread(() Console.WriteLine(Thread6: new TestF().GetHashCode()));t1.Start();
t2.Start();
t3.Start();
t4.Start();
t5.Start();
t6.Start();t1.Join();
t2.Join();
t3.Join();
t4.Join();
t5.Join();
t6.Join();
优缺点分析
优点 1.通过继承实现单例 2.可以通过单例基类规范统一标准 3.线程安全 4.无法通过除单例基类提供的静态属性instance以外的其它方式获取其派生类实例外部通过new关键字显示调用构造函数或反射等其它获取实例的方式创建派生类实例将触发异常 5.派生类的无参构造函数用于初始化 6.按需加载延迟初始化。 缺点 1.要求派生类的无参构造函数公开 2.派生类对外部始终开放无参构造函数无法避免new关键字的显式调用所触发的异常
版本改进
V1.1 1.将延迟初始化的工厂方法从Lambda表达式替换为本地静态方法因为_unlock相对于LazyT是外部引用所以不可避免存在创建闭包的开销所以改为本地静态方法进行改进 2._unlock在构造函数中进行重置会存在线程安全的问题放在作为延迟初始化的工厂方法的本地静态方法中可以保证线程安全。 ......
系列文章
继承实现单例模式的探索二
如果这篇文章对你有帮助请给作者点个赞吧