浅谈对单例模式的认识演变及代码实践

前端之家收集整理的这篇文章主要介绍了浅谈对单例模式的认识演变及代码实践前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

记得n年前从VB6开始学编程(那时对面向对象没有太深理解), VB里面有个Module-模块,用来放全局公用的函数,过程,常数,自定义结构,全局变量等等。等能用VB做些常用的软件了,开始转C#了,动手写程序的时候,突然觉得不适应,全局变量放哪里呢?(那时候真是有点菜菜),刚开始是用static。static 函数,static 变量,凡是想要全局用的都扔到一个static类里面。(其实全局常量和工具方法这么用也没错)但慢慢又发现不对了,静态方法无法调用示例方法啊,怎么办呢,傻眼了。


忘了从那里看到了单例模式,如获至宝,这不就是我要的么,简单易用?于是乎,程序中单例到处可见,当成万金油了,也没觉得有什么不好。那时候的单例大概是这么用的:


随着对面向对象认识的深入,越发的觉得单例模式不简单,有人批判,有人离不开,总而言之,没有最好的单例模式,只有最合适的。下面的代码分别演示了我见过的不同形式的用法,加入一点个人意见,算是抛砖引玉了。


(来自Robert C. Martin大牛的“敏捷软件开发”的一个例子)

怎么样,用属性是不是觉某些人觉得更.net。

加了锁,防止多个线程同时第一次访问,初始化的时候带来线程不同步的隐患(如果Singleton构造函数中有不少逻辑的话,线程同步的问题就很明显了)。


还是在Robert的书中看到他这么用,并且提示是利用的了.net的初始化功能没用if语句来避免多次创建,我很理解,但是没有锁,会不会有隐患呢?困扰了我好一阵,直至看了Jeffrey Richter的“CLR via C#”,书中谈到类型构造器,是这么说的,“CLR希望确保在每个AppDomain中,一个类型构造器只执行一次。为了保证这一点,在调用类型构造器时,调用线程要获取一个互斥线程同步锁。这样一来,如果多个线程试图同时调用某个类型的静态构造器,只有一个线程才可以获得锁,其他线程会被阻塞(blocked)。第一个线程会执行静态构造器中的代码。当第一个线程离开构造器后,正在等待的线程将被唤醒,然后发现构造器的代码已经被执行过。因此,这些线程不会再次执行代码,将直接从构造器方法返回。”从而得出结论:“由于CLR保证一个类型构造器在每个AppDomain中只执行一次,而且(这种执行)是线程安全的,所以非常适合在类型构造器中初始化类型需要的任何单实例(Singleton)对象”。


身边的一位哥们总爱这么用,问他为什么,他也不知道。现在理解了,static SingletonInstance中的初始化是线程安全的,但是为啥要放在嵌套类中呢??向下面这样不就得了?

另外,还是从Jeffrey的书中看到上面代码和下面代码是等效的:

C#提供了简单的语法来初始化类型的静态字段,生成上述代码时,编译器自动为Singleton类生成一个类型构造器 static SomeType(){ Instance = new Singleton; },呵呵,代码是不是越来越短了?

该结束了,关于单例模式的话题很深奥,我在Christian Gross的“.Net 2.0模式开发实战中”还看过一种通用的基于泛型的读-写线程安全的可复用的单例,一个程序中所有单例类实现不必丢的到处都是,最终用法类似于

可复用,线程安全,并且单例允许传入参数,一劳永逸,哈哈。代码太长了,就不再引用了,有兴趣的人找书看吧。现在我的代码中,单例的使用越来越谨慎了,有很多好的模式可以用,不要把单例当成万能解决方案,要看到单例的隐患和复杂性,从而选择最合适的用法

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/icyhy/archive/2011/06/16/6549568.aspx

猜你在找的VB相关文章