关于单例模式与静态变量的使用场景

honkerhero 2010-03-30 11:55:53
谁能给清楚的描述一下它们分别的使用场景,最好举两个特别明显的例子。
或者能从理论上说清楚也可以。
...全文
1183 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
tmoonlight 2010-04-03
  • 打赏
  • 举报
回复
2001 mark 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
lzsh0622 2010-04-03
  • 打赏
  • 举报
回复
静态变量是结构化编辑时代的老概念——变量的延续.
单例是面向对象的概念,单实例类.

例如:在服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。
管理过程中,一些中间耗时检测过程不用重复执行,带来响应速度的优化。

不是必须这样,用普通类也一样实现,每次应用前实例化,用完销毁,相对来说性能差一些而已。
lzsh0622 2010-04-03
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 honkerhero 的回复:]
1、静态变量在程序中也是唯一的,
2、单例中的单个实例其实也是以静态变量的方式存的

我只想知道,什么场景下必须用单例,而不是静态变量?还是说他两仅仅是设计上的东西。
[/Quote]

静态变量与单例不是一类概念,没有可比性。

什么场景下必须用单例? 这种说法也不成立。 是优劣选择问题?不是必须这样。
honkerhero 2010-04-03
  • 打赏
  • 举报
回复
没人拿分么?
honkerhero 2010-04-02
  • 打赏
  • 举报
回复
楼上各位,你们说的单例的优点什么的,偶都知道,我现在想知道的是区别?

1、静态变量在程序中也是唯一的,
2、单例中的单个实例其实也是以静态变量的方式存的

我只想知道,什么场景下必须用单例,而不是静态变量?还是说他两仅仅是设计上的东西。

那个五星的说了一堆,不知所云。任何模式在使用时都应该有其必然的理由,否则就成了为了设计而设计,举个场景好不。
小_虎 2010-04-01
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 sp1234 的回复:]
当时我跟对方的老板说:一些更加纯的面向对象语言、以及动态语言,甚至没有static概念,甚至没有Interface而只有class,难道他们就不能实现Sington?他们是更加纯的OO语言,他们只要被测试者测试出Instance总是唯一的就对了!那个老板一片茫然,我也就懒的争论了。
[/Quote]
呵呵。。。
想多听听大哥当年的故事。。
ctwei86 2010-04-01
  • 打赏
  • 举报
回复
在C#中基本是靠类为单位来组织程序的,类中主要包括两个方面:属性和方法,其中属性是用来描述或者说是用来记录和传递数值的,方法是用来“做”事情的。一个类相当于一个“模板”,利用这个模板可以new出很多的对象,这一个个的对象在本质上存在于一段段的内存中。
单例模式的意图在于,有的类,比如说是工具类,它里面没有任何的属性,只有方法,因此,从某种意义上来说,这样的类只用创建一个就够了,多次的创建只会浪费内存,浪费时间。这也是享元模式的一个很重大的意义。或者在有的不大的ASP.NET的项目中,干脆直接把业务逻辑层和数据访问层的类直接写成静态的也差不多是这个意思。
C#中静态变量是在程序初始化的时候就分配内存,并且它是属于类的,换句话说,如果某公共类中有一个公共的变量,那么通过类名.变量名就可以访问这个变量了。
单例模式的使用场景,好像有一个挺常用的地方就是读配置文件,一个程序在初始化的时候,配置文件一般只用读一次,因此就很使用用单例模式。利用单例模式读取配置文件,然后每次要用的时候去单例模式里面的对象中去取就可以了,不用在一遍一遍的再去读,浪费时间,也浪费效率。
  • 打赏
  • 举报
回复
当时我跟对方的老板说:一些更加纯的面向对象语言、以及动态语言,甚至没有static概念,甚至没有Interface而只有class,难道他们就不能实现Sington?他们是更加纯的OO语言,他们只要被测试者测试出Instance总是唯一的就对了!那个老板一片茫然,我也就懒的争论了。
cjnkd 2010-04-01
  • 打赏
  • 举报
回复
帮顶一个
  • 打赏
  • 举报
回复
如果你只是关心内存分配这么底层的东西,很自然地就会把Instance定义为 static 的方法。因此我们在一个static的工厂类中定义一堆static的Instance相比,singleton确实看起来是脱裤子放屁地多余的。


于是一些认为GOF很权威的人就想出了规矩:强调此class的.ctor实例化方法必须定义为internal。我5年前在应聘架构师时就因为说出了“只要实现的Instance是业务上唯一的对象,写不写internal并不是最重要的”而被对方认为技术不行。呵呵,如果仅仅纠缠于书本上的技术算个什么?
  • 打赏
  • 举报
回复
如果你纠缠于对象内存分配在哪里,就会绕进泥沼里。设计模式都是“设计”模式,不是给你规定内存如何分配的。只有站在设计的角度,考虑到不同的底层实现平台/语言的共性,才能理解“设计”为什么要搞出一点小玩意还称为模式。

所有设计模式都有明确的接口,singleton也不例外。因此,Instance就是依据接口协议就可以访问的。例如我们处理一堆“帖子”,假设帖子对象具有 I可计数 接口,我们就从帖子中取出计数器来加一,否则我们就在我们全局static的计数器去加一。这就是一种随着项目不断扩展重构而在最简单的架构上增加了灵活性的实现。

honkerhero 2010-04-01
  • 打赏
  • 举报
回复
顶啊,没人给答案么?
tashiwoweiyi 2010-03-31
  • 打赏
  • 举报
回复
好吓人啊
honkerhero 2010-03-31
  • 打赏
  • 举报
回复
大家不要回复这些基础的东西啊。

静态变量是不能回收的,i know.

其实上单例模式里面就包含自己的静态引用吧?

我只是想知道,要实现系统只有一个实例,什么时候只能用静态变量,不能用单例模式?
或者说,什么时候只能用单例模式,不能用静态变量?
段传涛 2010-03-30
  • 打赏
  • 举报
回复
个人认为,为了方便,特别是一个人做项目是,用静态变量还是不错的。
还有 就是递归or 引用时,静态就能显示他的特点了。
段传涛 2010-03-30
  • 打赏
  • 举报
回复
楼主的这个问题比较牛。正好来学习讨论一下。我是用缓存多,静态变量少
静态变量是GC的根。按照GC的回收规则,根是不会被回收的。
静态变量最大的问题应该就是内存释放的问题,这个问题在大型的项目中尤为明显,而且一般情况下都是不被察觉的情况下被滥用。
比如:一个静态变量隐式的引用了this,这种情况下可能会导致this不会被释放,this可能是一个page也可能是一个其他对象,这将导致连锁反映,所有和this有引用关系的对象都会被Hold住,在垃圾回收的时候这些对象将不会被释放。
静态属性没有任何问题,静态方法也没有,这些属性和方法是在类型对应的方法表中。

但是静态变量也不是不能使用,只是使用的时候要格外的小心,其方便性不言而喻。

WebForm和WinForm里面静态变量的内存布局是一样的(都在托管堆上),所以他们没有本质的区别,只是应用的场景不同而已。
private static IdealWebSite.BLL.Company _cm = new IdealWebSite.BLL.Company();
private static IdealWebSite.Model.Company _company = new IdealWebSite.Model.Company();
private static Regex _rx;

这些将对象是根,不会被释放,如果你的程序中有引用这些对象的地方要格外小心。
特别安静 2010-03-30
  • 打赏
  • 举报
回复
polarissky 2010-03-30
  • 打赏
  • 举报
回复
向风语者大哥学习,面试的时候考了一个单例模式
zzxap 2010-03-30
  • 打赏
  • 举报
回复
静态变量大家肯定比较熟悉,使用静态变量就是为了维护一个状态,
使得可以让多实例共享这个变量,我们可以用它来实现一些类似缓存的功能。
现在如果这个类的实现是一个单例的模式,那么静态变量就失去了优势。
单例,那就意味着只能多线程使用,那么多线程中实例变量就是多线程共享的(非线程安全),
此时实例变量的作用类似于静态变量了。


但是个人观点,不提倡使用实例变量,毕竟非线程安全。如果一定要使用的话,个人观点只用实例变量来维护一些web资源(缓存功能,如xml资源等等,公司项目中有很多这样的情况),不能在这个类中频繁使用它,不安全(我遇到的就是这样一个问题)。
zzxap 2010-03-30
  • 打赏
  • 举报
回复
就是说无论你new了多少次,静态的变量都只会有一个,而且不需要实例化,就可以访问

110,578

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧