说说设计模式~单件模式(Singleton)

简介:

单件模式(Singleton)要求一个类有且仅有一个实例,并且提供了一个全局的访问点。

从概念上来研究一下它的实现,不考虑线程安全

 1 public sealed class Singlton
 2 {
 3     static Singlton instance = null;
 4     private Singlton() { }
 6  
 7     public static Singlton Instance
 8     {
 9         get
10         {
11             if (instance == null)
12             {
13                 instance = new Singlton();
14             }
15             return instance;
16         }   
17     }   
18 }

上面的实现方式,对于多线程会有问题,因为Singlton 对象可能不指一次被创建,而罪魁祸首就是if (instance == null)这句话,它并不是线程安全的。

如果希望实现线程安全的单件,我们最先想到的应该就是借助lock机制来实现,代码可能是这样:

 1 public sealed class Singlton
 2 {
 3     static Singlton instance = null;
 4  
 5     static readonly object o = new object();
 6  
 7     Singlton()
 8     { }
 9  
10     public static Singlton Instance
11     {
12         get
13         {
14             lock (o)
15             {
16                 if (instance == null)
17                 {
18                     instance= new Singlton();
19                 }
20             21             }
return instance;
22 } 23 } 24 }

而我们使用静态对象在静态结构方法里为它进行初始化,这种方式也非常在程序中看到,如:

 1 public sealed class Singlton
 2 {
 3     static readonly Singlton instance = null;
 4  
 5     static Singlton()
 6     { instance = new Singlton();}
 7  
 8     public static Singlton Instance
 9     {
10         get
11         {
12             return instance;
13         }
14     }
15 }

这种方法及其它单件模式有一个问题,就是如果希望去更新单件对象的值,是无法实现的,比如,instance对象希望从数据库中取出一个列表,而列表的信息有可能

发生变化,怎样保证instance里取的是最新的信息呢,这样我们可以在单件中引入时间触发器的概念,代码如下:

 1     public class CategoryRepository : Car_RentalRepositoryBase, ICategoryRepository
 2     {
 3         #region 静态树结构,每1分钟去获一下数据库
 4         static List<Category> categoryList = null;
 5         /// <summary>
 6         /// 数据实体
 7         /// </summary>
 8         public static volatile List<Category> Instance = null;
 9         static CategoryRepository categoryRepository = new CategoryRepository();
10         static System.Timers.Timer sysTimer = new System.Timers.Timer(600000);
11         static CategoryRepository()
12         {
13             Reload();//第一次加载
14             sysTimer.AutoReset = true;
15             sysTimer.Enabled = true;
16             sysTimer.Elapsed += new System.Timers.ElapsedEventHandler(sysTimer_Elapsed);
17             sysTimer.Start();
18         }
19 
20         /// <summary>
21         /// 被订阅了Elapsed事件的方法,每隔一段时间去重新获取数据列表
22         /// </summary>
23         /// <param name="sender"></param>
24         /// <param name="e"></param>
25         static void sysTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
26         {
27             Reload();
28         }
29 
30         internal static void Reload()
31         {
32             categoryList = categoryRepository.GetModel().OrderBy(i => i.SortNumber).ToList();
33             Instance = categoryList.Where(i => i.ID != 1).ToList();
34         }
35 }

这种方式解决了实例不能获取最新的问题。

最后,奉献出国外牛人写了的泛型单件类,如果实现的类直接继承它即可。

 1  /// <summary>
 2     /// 泛型单例基类
 3     /// </summary>
 4     public abstract class Singleton<TEntity> where TEntity : class
 5     {
 6         private static readonly Lazy<TEntity> _instance
 7           = new Lazy<TEntity>(() =>
 8           {
 9               var ctors = typeof(TEntity).GetConstructors(
10                   BindingFlags.Instance
11                   | BindingFlags.NonPublic
12                   | BindingFlags.Public);
13               if (ctors.Count() != 1)
14                   throw new InvalidOperationException(String.Format("Type {0} must have exactly one constructor.", typeof(TEntity)));
15               var ctor = ctors.SingleOrDefault(c => c.GetParameters().Count() == 0 && c.IsPrivate);
16               if (ctor == null)
17                   throw new InvalidOperationException(String.Format("The constructor for {0} must be private and take no parameters.", typeof(TEntity)));
18               return (TEntity)ctor.Invoke(null);
19           });
20 
21         public static TEntity Instance
22         {
23             get { return _instance.Value; }
24         }
25     }

感谢您好阅读,希望本文章对您有帮助。

相关链接:基础才是重中之重~延迟初始化

参考 文献:

http://technet.microsoft.com/zh-cn/magazine/dd997286%28VS.95%29.aspx

http://www.fascinatedwithsoftware.com/blog/post/2011/07/13/A-Generic-Singleton-Class.aspx

 本文转自博客园张占岭(仓储大叔)的博客,原文链接:说说设计模式~单件模式(Singleton),如需转载请自行联系原博主。

目录
相关文章
|
设计模式 存储 安全
【设计模式——学习笔记】23种设计模式——单例模式Singleton(原理讲解+应用场景介绍+案例介绍+Java代码实现)
【设计模式——学习笔记】23种设计模式——单例模式Singleton(原理讲解+应用场景介绍+案例介绍+Java代码实现)
48 0
|
2月前
|
设计模式 安全 Java
设计模式--单例模式Singleton
这篇文章详细介绍了单例模式Singleton的八种实现方式,包括饿汉式(静态常量和静态代码块)、懒汉式(线程不安全和线程安全的同步方法、同步代码块)、双重检查、静态内部类和枚举。每种方式都有详细的代码示例和优缺点说明,帮助理解单例模式的应用和选择适合的实现方法。
设计模式--单例模式Singleton
|
5月前
|
设计模式 存储 安全
技术好文共享:设计模式笔记:单件模式(Singleton)
技术好文共享:设计模式笔记:单件模式(Singleton)
32 0
|
6月前
|
设计模式 缓存 安全
设计模式 - 创建型模式_ 单例模式 Singleton Pattern
设计模式 - 创建型模式_ 单例模式 Singleton Pattern
77 0
|
6月前
|
设计模式 安全 Java
设计模式-单例 Singleton
设计模式-单例 Singleton
39 1
|
6月前
|
设计模式 存储 Java
Java设计模式:解释一下单例模式(Singleton Pattern)。
`Singleton Pattern`是Java中的创建型设计模式,确保类只有一个实例并提供全局访问点。它通过私有化构造函数,用静态方法返回唯一的实例。类内静态变量存储此实例,对外仅通过静态方法访问。
49 1
|
设计模式 数据库连接 数据库
单例 (Singleton)设计模式介绍
单例 (Singleton)设计模式介绍
88 1
|
设计模式
设计模式3 - 单例模式【Singleton Pattern】
设计模式3 - 单例模式【Singleton Pattern】
31 0
|
设计模式 安全 Java
《Java极简设计模式》第01章:单例模式(Singleton)
介绍创建Java单例对象的七种方式,重点掌握哪些创建方式是线程安全的,哪些方式是线程不安全的,并能够在实际项目中灵活运用设计模式,编写可维护的代码。
164 2
|
设计模式 架构师 Java
架构系列——架构师必备基础:设计模式之单例模式(Singleton Pattern)
架构系列——架构师必备基础:设计模式之单例模式(Singleton Pattern)