我在之前的Stack Overflow回答中写下了我对静态类的想法:
类使用单一方法—最佳方法?
我曾经喜欢充满静态方法的实用程序类。他们对辅助方法进行了很大的整合,否则这些方法会导致冗余和维护的麻烦。它们非常容易使用,没有实例化,没有处理,只是“fire'n'forget”。我想这是我第一次无意中尝试创建面向服务的体系结构——许多无状态服务只做它们的工作,而不做其他事情。然而,随着系统的发展,龙将会到来。
多态性
Say we have the method UtilityClass.SomeMethod that happily buzzes along. Suddenly we need to change the functionality slightly. Most of the functionality is the same, but we have to change a couple of parts nonetheless. Had it not been a static method, we could make a derivate class and change the method contents as needed. As it's a static method, we can't. Sure, if we just need to add functionality either before or after the old method, we can create a new class and call the old one inside of it - but that's just gross.
接口问题
由于逻辑原因,静态方法不能通过接口定义。因为我们不能重写静态方法,所以当我们需要通过接口传递静态类时,它们是无用的。这使得我们无法将静态类用作策略模式的一部分。我们可以通过传递委托而不是接口来修补一些问题。
测试
这基本上与上面提到的界面问题密切相关。由于我们交换实现的能力非常有限,我们也会在用测试代码替换生产代码时遇到麻烦。同样,我们可以将它们包装起来,但这将需要我们更改大部分代码,以便能够接受包装器而不是实际的对象。
促进团
由于静态方法通常用作实用方法,而实用方法通常有不同的目的,我们很快就会得到一个充满不一致功能的大类——理想情况下,每个类在系统中都应该有一个单一的目的。只要目的明确,我宁愿上五倍的课。
蠕变参数
To begin with, that little cute and innocent static method might take a single parameter. As functionality grows, a couple of new parameters are added. Soon further parameters are added that are optional, so we create overloads of the method (or just add default values, in languages that support them). Before long, we have a method that takes 10 parameters. Only the first three are really required, parameters 4-7 are optional. But if parameter 6 is specified, 7-9 are required to be filled in as well... Had we created a class with the single purpose of doing what this static method did, we could solve this by taking in the required parameters in the constructor, and allowing the user to set optional values through properties, or methods to set multiple interdependent values at the same time. Also, if a method has grown to this amount of complexity, it most likely needs to be in its own class anyway.
要求使用者毫无理由地创建类的实例
One of the most common arguments is: Why demand that consumers of our class create an instance for invoking this single method, while having no use for the instance afterwards? Creating an instance of a class is a very very cheap operation in most languages, so speed is not an issue. Adding an extra line of code to the consumer is a low cost for laying the foundation of a much more maintainable solution in the future. And finally, if you want to avoid creating instances, simply create a singleton wrapper of your class that allows for easy reuse - although this does make the requirement that your class is stateless. If it's not stateless, you can still create static wrapper methods that handle everything, while still giving you all the benefits in the long run. Finally, you could also make a class that hides the instantiation as if it was a singleton: MyWrapper.Instance is a property that just returns new MyClass();
只有西斯才会做绝对的事
当然,我不喜欢静态方法也有例外。真正的实用程序类不会造成任何膨胀风险,这是静态方法的绝佳案例- System。以Convert为例。如果您的项目是一次性的,不需要将来进行维护,那么整个体系结构真的不是很重要——静态或非静态并不重要——但是开发速度很重要。
标准,标准,标准!
使用实例方法并不会限制您使用静态方法,反之亦然。只要区分的背后是有原因的,而且是标准化的。没有什么比查看一个扩展了不同实现方法的业务层更糟糕的了。