何时在C#中使用静态类

这个问题在这里已经有了答案:

  • 单一方法类 - 最佳方法? 14个答案

  • 我在早期的Stack Overflow答案中写下了我对静态类的想法:使用单一方法的类 - 最佳方法?

    我曾经喜欢充满静态方法的工具类。 他们对辅助方法进行了大量整合,否则这些方法会导致冗余和维护地狱。 它们非常易于使用,不需要实例化,不需要处理,只需点燃即可。 我想这是我第一次创建面向服务架构的第一个不知情的尝试 - 很多无状态的服务只是做了他们的工作,没有其他任何东西。 随着系统的发展,龙即将到来。

    多态性

    假设我们有方法UtilityClass.SomeMethod,它可以愉快地发出嗡嗡声。 突然我们需要稍微改变功能。 大部分功能都是一样的,但我们必须改变几个部分。 如果它不是一个静态方法,我们可以创建一个派生类并根据需要更改方法内容。 由于这是一种静态方法,我们不能。 当然,如果我们只需要在旧方法之前或之后添加功能,我们可以创建一个新类并在其中调用旧类,但这只是粗略的。

    界面的困扰

    出于逻辑原因,无法通过接口定义静态方法。 由于我们无法重写静态方法,因此当我们需要通过接口传递它们时,静态类就没有用处了。 这使我们无法将静态类用作策略模式的一部分。 我们可以通过传递代表而不是接口来修补一些问题。

    测试

    这基本上与上面提到的接口问题一起。 由于我们交换实现的能力非常有限,因此我们也很难用测试代码替换生产代码。 再次,我们可以将它们包装起来,但是它需要我们改变代码的很大一部分,以便能够接受包装器而不是实际的对象。

    促进斑点

    由于静态方法通常用作实用方法,而实用方法通常会有不同的用途,所以我们很快就会得到一个充满非一致性功能的大类 - 理想情况下,每个类在系统中应该有一个单一的用途。 只要他们的目标明确,我宁愿有五倍的班级。

    参数蠕变

    首先,那个可爱又天真的静态方法可能需要一个参数。 随着功能的增长,添加了一些新的参数。 不久,将添加更多可选的参数,因此我们创建方法的重载(或仅添加默认值,支持它们的语言)。 不久之后,我们有一个方法需要10个参数。 只有前三个是真正需要的,参数4-7是可选的。 但是,如果指定了参数6,那么也需要填充7-9 ...如果我们创建了一个具有执行此静态方法的单一目的的类,我们可以通过获取所需的参数来解决此问题构造函数,并允许用户通过属性设置可选值,或者同时设置多个相互依赖的值。 另外,如果一种方法已经发展到这种复杂程度,那么无论如何它最有可能需要在自己的类中。

    要求消费者没有理由地创建一个类的实例

    其中一个最常见的观点是:为什么要求我们班的消费者创建一个实例来调用这个单一的方法,而之后没有使用实例呢? 在大多数语言中创建类的实例是非常便宜的操作,所以速度不是问题。 向消费者添加额外的代码行是为未来奠定更可维护解决方案基础的低成本。 最后,如果你想避免创建实例,只需创建一个允许轻松重用的类的单例包装器 - 尽管这确实要求你的类是无状态的。 如果它不是无状态的,那么您仍然可以创建静态包装方法来处理所有事情,同时仍然可以长期为您提供所有好处。 最后,你也可以创建一个隐藏实例的类,就好像它是一个单例:MyWrapper.Instance是一个只返回new MyClass();的属性new MyClass();

    只有西斯以绝对价格交易

    当然,我不喜欢静态方法也有例外。 真正的实用工具类不会对膨胀造成任何风险,这是静态方法的绝佳例子 - 以System.Convert为例。 如果您的项目是一次性的,对未来的维护没有任何要求,那么整体架构确实不是非常重要 - 但静态或非静态并不重要 - 开发速度确实如此。

    标准,标准,标准!

    使用实例方法不会阻止您使用静态方法,反之亦然。 只要有分化背后的推理,并且它是标准化的。 没有什么比通过不同的实现方法来查看业务层更糟糕了。


    当决定是否使类为静态或非静态时,您需要查看您想要表示的信息。 这需要更多的“ 自下而上 ”的编程风格,专注于首先代表的数据。 你正在写一个类似岩石或椅子的真实世界对象吗? 这些东西都是物理的,并且具有物理属性,例如颜色,重量等,这些属性告诉您可能需要实例化具有不同属性的多个对象。 我可能同时需要一把黑色椅子和一把红色椅子。 如果您同时需要两种配置,那么您立即知道您将要将其实例化为对象,以便每个对象可以是唯一的并且同时存在。

    另一方面,静态函数更倾向于不属于真实世界对象或可以轻松表示的对象的行为。 请记住,C#的前身是C ++和C,您可以在其中定义不存在于类中的全局函数。 这更倾向于“ 自上而下 ”的编程。 静态方法可以用于这些情况下,“对象”执行任务没有意义。 通过强制你使用类,这样可以更容易地将相关的功能分组,这有助于你创建更多可维护的代码。

    大多数类可以用静态或非静态表示,但是如果您有疑问,可以返回到您的OOP根目录,并尝试考虑您所代表的内容。 这是一个执行动作的对象(可以加速,减速,转弯的汽车)或更抽象的东西(如显示输出)。

    联系你的内部面向对象,你永远不会出错!


    对于C#3.0,扩展方法可能只存在于顶级静态类中。

    链接地址: http://www.djcxy.com/p/13815.html

    上一篇: When to use static classes in C#

    下一篇: Why is the Borg pattern better than the Singleton pattern in Python