静态方法和单件模式具体区别在哪里? 

什么情况下将方法设计为静态的?静态方法只能操作静态字段,属于类的方法,不属于类的某个对象。

如果方法只是实现数据库的操作,是不是应该设计为静态的,还是将类设计为单件?

单件模式的类在运行时只有一个实例,也就是说其他对象都使用这个实例进行操作,那为什么不把这个类的所有方法都设计为静态的呢,那样岂不是更简单。

还有一个问题是如果一个类的方法太多(几百个),在实例化的时候会不会带来性能损失?

在new一个对象时,系统在托管堆上为类的字段分配内存,和一个32位的指针指向类的方法列表,这些方法的地址占空间了吗?



Singleton是一个静态的实例,是一个对象

包含了静态方法和数据

其它对象调用它只是把参数传递给这个实例对象

代码段和数据段都在这个实例空间运行

因为是静态的,所以效率会高一些

只是要动态生成实例一次

将方法设计为静态的,是一些全局的函数,

一堆操作在一起应该是一个接口

数据段在调用者空间内

代码段在静态区

感觉没有必要作成单件,这种条件不是应用单件模式的情况



对单件模式没研究,,

就一个类而言,他要包含上百个方法??没有哪个人会这样设计一个类吧

这样就失去了OOP的意义,在类的设计上一定要有足够的粒度,这样才能更好的复用和维护。

我是这样考虑的,但就搂主的问题而言...我还真不是很明白



// 单件模式的类在运行时只有一个实例,也就是说其他对象都使用这个实例进行操作,那为

// 什么不把这个类的所有方法都设计为静态的呢,那样岂不是更简单。

.NET可以使用静态方法作为Singleton模式的实现,但是如果这么设计那么这个class就失去了面向对象的所有特性,有时候我们还是需要让这个class继承其他class,或者让其他class继承,等等类似问题

// 还有一个问题是如果一个类的方法太多(几百个),在实例化的时候会不会带来性能损失

不会

不过是一个函数指针列表,能占用多大空间?



------------------------------------------------------------

如果所有的方法都是静态的,那就根本不需要任何实例。有人把这种类叫做工具类,这种做法叫做工具类模式。

工具类模式基本上不需要面向对象的概念。

当然,我不是说面向对象的技术就一定比面向过程的好很多,但是如果你是在使用Java这样的面向对象的语言,设计一个面向对象的系统,那么一个单纯的想法就是尽量靠近面向对象的概念。我没有见过一个使用Java的人反其道而行之,努力使用面向过程的概念。如果你是面向过程概念的拥护者,不妨选择一个像Fortran这样的结构化编程语言。

在大多数的情况下,工具类中的方法都描述一些实体,应该把这些方法移动到描述这些实体的类中去。如果没有这些类,那就不妨考虑创建它们。

我曾经见到过一个很大的工具类,都是对String的操作。经过辨认,发现这些操作实际上都是为了组合URL准备的,并不是一般性地针对任何的String。为什么不把它们放到一个CustomizedURL类中去呢?

当你这样做了之后,会发现你并不需要一个很大的工具类,或者根本就可以取消它。

单例模式并不是一个取代工具类模式的好候选人。单例模式的情况在多JVM的J2EE服务器环境中变得很复杂。单例对象一旦创建出来就不会被湮灭,浪费内存。



明白了,静态方法不属于对象,也就不是面对对象的设计了,一个类全是静态方法,还不如不设计这个类。

这二天看微软asp.net论坛的代码看迷糊了,里面对每一个实体类基本都有一个数据操作类,里面全是静态方法,直接封装到实体类中应该更好。

还有数据提供类,继承抽象类,里面的方法太多了,不知道为什么不拆分成多个类,并且实现接口而不是继承抽象类。

谢谢大家的指点!谢谢!



正确的应该问:为什么不能用类的静态方法代替单件模式中创建出的对象中所包含的实例方法呢(或者反过来问也可以)?  

如果问对了问题,自然就能看出答案。  

类的实例-对象-要是和类一样了,那要对象/类有什么用呢,只留下类/对象不就可以了么?



单例模式(Singleton),也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。


实现单例模式的思路是:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。


对JAVA而言,单例模式在多线程的应用场合下必须小心使用。如果当唯一实例尚未创建时,有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自创建了一个实例,这样就有两个实例被构造出来,从而违反了单例模式中实例唯一的原则。解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁(虽然这样会降低效率)。


对.NET没有这个问题.


静态方法是类所具有的方法,不论该类有多少实例,都只有一份,由于这个特性,将他用在了Singlton模式中。


而单例模式,本身是面向应用的--因为多人开发时,你不希望你写的类被实例化多次,你只希望系统中你的类就只有一个实例。由于有此需求,所以有了单例模式。

显然,如果你能通过某种手段,要求所有开发人员,你写的XX类已经实例化了,请不要在实例化了。那么你可以不用单例模式。--不过这对团队开发,可能吗?




静态方法不属于对象,属于类,是类型方法,而不是对象的方法,这样理解对吗?

一个类中如果有些方法不属于具体某个对象就设计成静态了,如果一个类在系统运行中只想有一个实例,就设计成单件,对不对?

应该可以结贴了


我个人是这么认为的,Singleton模式的类一般是管理类,它只提供一个类的实例,属于最高管理层,不可撤消,由这个管理层来提供一组方法实现对其他对象的管理或加以控制,这些方法之间在逻辑上可能并不相关,但都可以统一到一个抽象的高层管理对象中去;还有,我认为Singleton模式的实现是不考虑继承的,而且也不应该被继承,因为从Singleton派生的类并不是Singleton,如果要使它成为Singleton,必须添加相关的静态函数和变量;

静态方法的设计原则,其实很简单,如果方法本身与实例无关,只与类(高层抽象)相关,那么我们就把它设计成静态方法,比如String.Equals(a,b).静态方法应该直接反映类本身。

以上其实讲的还不是特别清楚,因为仍然觉得可以用静态方法替换Singleton来实现,但Singleton模式提取一个对象实例并不是没有意义的,有一个显著的好处就是跨平台,跨应用程序域,Java下有RMI(可惜本人还不熟悉,不多说了),在.net remoting下,进行远程对象调用时,服务器端激活提供了两种方式,其中一种就是Singleton模式,如果两个应用程序域要通信的类都采用静态方法,那将无法实现这种调用。




当然不是,如果只保留类,在设计上会带来相当大的麻烦,OO给程序设计上带来了一次革命性的变化,让人如沐春风;但设计最终追求的更高层的抽象,OO只不过是在追求更高层抽象过程中的一次过渡,但它只好还会统治很长的一段时间,下一代的设计OX不知道是怎么个样子,我们做开发的,一定要打好OO的基础,同时在进行设计的过程中,不断进行优化,遵循一条原则,追求更高级的抽象.



单例和static方法本身是两个不同的概念,我都没想过把两者放在一起去讨论。  

单例是一个非常简单的模式,说白了就是在某个范围内(通常是内存)保持一个类的唯一的一个实例,作用保持实例的唯一性,常用类可防止频繁的new操作,比如全局配制类,Log等。  

而static method,正如有人所说,一般是在工具类中使用。  

初学设计模式的人,才会有这样的疑问,用多了,这就不成问题了。。。话说回来,其实带着这样的问题学其它的模式,还更好。  

学设计模式,还是《Java与模式》这本书,是最好的,因为是中国人(至少算华人吧)写的,不像翻译过来的书,翻译的不明不白。  

对于daou101(海天一鸥) 兄弟最后一句话:

"显然,如果你能通过某种手段,要求所有开发人员,你写的XX类已经实例化了,请不要在实例化了。那么你可以不用单例模式。--不过这对团队开发,可能吗?"

这种疑问,显然是还没有用过单例,因为,做为一个单例类,最基本的就是要做到不能被外界使用new 来实例化,一般的构适函数都是private的,这个类对外界的入口只有一个,你想通过其它方法实例化都不可能的,呵呵。



wacle([Smile!]) 既然觉得不能仅仅保留类而去掉实例化类的功能,怎么还会有“仍然觉得可以用静态方法替换Singleton来实现”的疑问呢?



我说这句话只是就之前的分析得出的结论,要实现一种功能还不简单,粗糙的设计依然能实现某种需要,经验告诉我们,拙劣的设计是要付出代价的。



说个简单的就说分页处理的时候就要用到static.

数据库的连接就可以把他那出来做为一个单件.



从表面上看,静态(static)成员可以通过 类名.成员名 来直接调用,而实例(instance)成员需要生成一个对象后才能调用。同一个操作,性能当然静态成员好

但其实区别是跟对象设计有关的,一般来说实例成员跟实例的状态有关,某个方法的调用可能需要访问当前对象的状态,并改变其状态,从而影响其他方法的结果

而静态成员是跟类本身有关,与单独的实例状态无关。但静态成员不要太多了,否则就沦为以前的procedural programming风格了,也许对象需要重新设计或重构

静态成员往往会在多线程下操作,需要做同步化控制



要解决此问题,首先要知道面向对象的基础知识,其次是设计模式.活活



这样理解就行了:

静态方法是单件模式的一种实现手段。



有个疑问,如果用Singleton的话,对象永远只有一个,那如果是WEB程序,自然可能会承受很大的并发,这时候怎么处理?全部对这个对象操作?那不很容易乱套?如果锁上,就全部排队?是不是很不合适呢?



to cnlamar:

呵呵,模式是用来解决特定问题的,如果会产生并发问题,自然不应该用。