什么时候考虑使用静态
Contents
什么时候考虑使用静态
静态方法比较少用,因为他在一启动就实例化了,比较占资源,当然,配合单例模式还是比较好用的
比较多的用在数据连接上,我避免使用的原则就是减少资源消耗
静态方法用来执行无状态的一个完整操作,实例方法则相反,它通常是一个完整逻辑的一部分,并且需要维护一定的状态值。
如果用内存和效率来区分使用Static Method、Instance Method 就回到过去结构化编程了。使用那种方法的根本出发点还是围绕面向对象来进行的
静态方法不用创建实例可以直接调用
与类相关与对象无关
不需要对象的"轻"方法
工厂方法
如果某个方法是用频率较高,或者方法本身通用性较强,无需初始化类成员变量,则可以使用静态方法,那样方便,速度也快.
可以直接拿来就用的方法,就是静态的.
肯定不涉及具体对象,因为静态方法内,是无法直接使用任何非静态成员的。
工具类
可以当作"全局"对象或方法来使用
重载"操作符"
静态方法和实例方法是一样的,在类型第一次被使用时加载。调用的速度基本上没有差别。
从面向对象的角度上来说,在抉择使用实例化方法或静态方法时,应该根据该方法和实例化对象具是否有逻辑上的相关性,如果是就应该使用实例化对象, 反之使用静态方法。
我是把静态类当做全局变量和全局函数的整合对象来用的
全局累加时用
不需要生成对象的
经常频繁使用的
工具类里的 (如SqlHelper)
适当地使用static方法本身并没有什么,当一个人从来不懂使用多态、接口设计时,很自然地会滥用static方法。
个人理解在多个类中需要调用并且是与对象无关的方法可设为静态方法,方便调用。
所有对象共有的方法
不关系到任何于特定对象相关的操作
比如学生的年龄就是学生的相关。
修改学生的年龄就不适合用静态方法。
一般来说,如果你的方法里没有用到this关键字,
那就适合用静态方法
通常通用的类中一些常用的方法可以设计为静态类
只要是没有用到类的状态信息,只从参数获取信息的都可以为静态的
可以实现某些特殊的设计模式: 如Singleton
由于没有this指针,可以把某些系统API的回调函数以静态函数的形式封装到类的内部
可以封装某些算法,比如数学函数,如ln,sin,tan等等,这些函数本就没必要属于任何一个对象,所以从类上调用感觉更好
总之,从OOA/OOD的角度考虑,一切不需要实例化就可以有确定行为方式的函数都应该设计成静态的
以上这些各种说法,基本上都是正确的。但是,其中绝大多数是讲了"静态"和"实例"的区别,以及静态方法的特征。
很少有说到何时或是为什么要使用静态的。
静态包括静态类和静态成员 (静态方法 和 静态属性) ,既然搜索出来的这些说的都是静态成员 (基本上说的都是静态方法) ,那么我也就先仅对静态方法谈一谈自己的看法。
上中学数学,尤其是平面几何的时候,老师经常讲"定义"与"性质"的区别。“性质"只是它表现出来的特征而已,而"定义"才是真正的决定性的东西。
我觉得,静态方法的"定义"当然是 static 关键字了。没有用到this指针,这一点才是静态方法的首要"性质” (本质特征) 。像什么【共通】【全局】【单例模式】呀,那都是它的应用场景,或是说使用静态方法来达到的目的。
那么说到"何时该使用静态方法"其实是困扰很多程序员的苦恼问题。不明白这一点,也从一个侧面反映出对OO思想的理解不够,就很可能通过滥用静态方法已达到在面向对象的语言中继续进行面向过程的编程,这是很可怕的。
其实,方法是否涉及具体类的实例,或者简单的说是否涉及"数据” (如果使用就要用到this指针) 是决定是否使用静态方法的根部要因。然而,判断是否涉及到"数据"也是要看当前设计思路的。有时候不够OO的设计,可能会将本该设计到数据的实例方法,从"数据相关"变成"数据无关”。 (与OO不同,面向过程的编程就是将 方法 与 数据 分开) 在这样的设计思路下,你会发现怎么什么动作都是与数据无关的呢?恩,这就该开始滥用静态方法了。
本想举一个好一点的例子,但是时间匆忙,就简短说一下 Log 吧。有人认为写日志是一个工具在干活,应该是 Log.debug(…);
有人认为,日志记录器是个"小精灵"应该有血有肉, Log logger = new Log(); logger.debug(…);
可能你会认为,这要取决于Log类以及debug方法的复杂程度;
也许你会认为,这要看Log类中是否有"数据”,比如,输出Level;
也许还有其他理由。
而我觉得可以说是仁者见仁智者见智,也可以看做是不同的编程风格,也可以… 总之,需要细细体会了。
追加一个稍好一些的例子: 检查 TextBox 是否输入了数据,如果没有,则依据某一个ID,从配置文件中读取一句话 (错误信息) ,然后弹出,并将此 TextBox 的底色置成红色,再将焦点放到上面去。
如果你不希望这一系列的操作 (大概6-7行代码) 每次都要写一遍,你就会设法把它提炼为"共通”。
方法一: (静态)
C#代码
public class Checker
{
public static void CheckEmpty(TextBox textBox)
{
if (textBox.Text.Length == 0)
{
string msg = Properties.ReadMessage(“001”);
MessageBox.Show(msg);
textBox.BackColor = Color.Read;
textBox.Focus();
}
}
}
Checker.CheckEmpty(textBox1);
方法二: (实例)
C#代码
public class MyTextBox : TextBox
{
public void CheckEmpty()
{
if (this.Text.Length == 0)
{
string msg = Properties.ReadMessage(“001”);
MessageBox.Show(msg);
this.BackColor = Color.Read;
this.Focus();
}
}
}
MyTextBox textBox1 = new MyTextBox();
textBox1.CheckEmpty();
因为Swing使用的很少,所以就用WinForm的控件来举例子了,所以代码是C#的,其实没有关系,所有OO语言在这一点上都是一样的。
如果你不觉得【扩展】SDK的控件有多么恐怖,或者应为其他原因已经对其扩展了,那么我更推荐使用实例方法 (方法二) 。理由吗,对控件的检查本来就是和控件自身 (Text属性) 息息相关的,是活生生的。
(这里不讨论读配置文件、MessageBox 等操作是否违背开闭原则)
1.静态方法和实例方法其实在性能上没有区别,加载时机,和内存占用都一样,调用速度也没有区别。
2.早期的结构化编程,几乎所有的方法都是"静态方法”,引入实例化方法概念是面向对象概念出现以后的事情了,区分静态方法和实例化方法不能单单从性能上去理解,创建c++,java,c#这样面向对象语言的大师引入实例化方法一定不是要解决什么性能、内存的问题,而是为了让开发更加模式化、面向对象化。这样说的话,静态方法和实例化方式的区分是为了解决模式的问题。
3.开发时如何选择:
从面向对象的角度上来说,在抉择使用实例化方法或静态方法时,应该根据是否该方法和实例化对象具有逻辑上的相关性,如果是就应该使用实例化对象 反之使用静态方法,其实用两个方法在效率和性能上影响并不大,根据自己程序设计来解决问题。
http://www.cnblogs.com/chinhr/archive/2008/04/03/1135561.html
Author -
LastMod 2016-06-02