【问题标题】:Static Classes & Class design静态类和类设计
【发布时间】:2014-09-16 20:57:33
【问题描述】:

在设计我的数据访问层时,我想让我的所有类都是静态的,这样就不需要对象实例化,并且可以使用类名访问类的所有成员。

这是一个好方法吗?如果是,那么为什么我们需要一个实例类类型。它是否会对 n 个客户端想要访问我的 DAL 的应用程序的性能产生影响,然后可能会因为根本没有创建对象而导致管理请求出现问题?

我知道静态类不能被实例化,应该用于日志记录、实用程序方法等,因为所有对象都需要以类似的方式运行,假设所有 DAL 类的行为都有效/安全吗?相同的方式(具有相同的功能),因此使它们成为静态而不是实例化它。

请指教。

【问题讨论】:

  • 老实说,我使用静态类的唯一情况是抽象工厂和扩展方法类。不要仅仅因为它无处不在,所以就让它成为静态的。

标签: c# .net static


【解决方案1】:

该类型在概念上表示与实例相关的操作,或者不表示。性能在这里不是考虑因素。

如果您的方法没有状态,或者它们的状态被设计为在整个应用程序中的所有方法调用之间共享,那么该方法应该是静态的。如果需要在成员之间共享单独的状态但不与整个应用程序共享,那么它们需要是非静态的。该类型通常需要一个或另一个基于它在概念上所代表的内容。这不是一个实际的选择。

【讨论】:

  • 我有点不同意——在某些场景中,您实现了几个“服务”对象,这些对象实现了相同的接口,但做事不同。它们不必具有字段形式的状态。主要的是你不能通过使用静态方法调用来使用多态性——客户端也必须改变。
  • +1。但请参阅my answer below。对类的用户隐藏静态实现通常很有用。
  • @feO2x 要使多态性完全有意义,从根本上讲,它需要对象实例的概念。需要对要创建、传递等类型的实例有意义,以利用对不同类型的多个实例进行相同处理的想法。在这种情况下,您创建的类型的核心概念本质上是表示一种对象类型,而不是未连接到对象实例的操作。由于该类型在概念上与对象实例相关联,因此它应该具有非静态成员。
  • @Servy:我同意你的看法。但是在他的问题中,Immortal(或多或少)询问了为什么要使用对象实例的基本概念(“这是一个好方法吗?如果是,那么我们为什么需要一个实例类类型。”)。因此,我认为我应该向他指出使用对象而不是函数的好处。
【解决方案2】:

通常最好避免使用静态类,因为它们会在您的代码中引入紧密耦合。它们使单元测试变得更加困难,因为这些调用是“硬连线”的,不容易被排除。

最好将它们设为实例,但只实例化一个实例。如果您将此与依赖注入(即将 DAL 对象传递到需要它的类中)结合起来,那么您将获得更松散的耦合,并且可以传递存根版本以进行单元测试 - 查找 Unity 或 Castle Windsor 或其他 IoC 框架以了解这是如何实现的有效。

【讨论】:

    【解决方案3】:

    对性能有影响 - 静态方法调用比实例方法调用更快,尤其是在处理后期绑定时。但这也是面向对象编程的一大优势。

    如果您只使用静态类并因此使用静态方法调用,那么您就没有“交换对象”的能力——在我看来,这是面向对象编程中最重要的部分。查看面向对象设计的 SOLID 原则,您将了解这种编程风格的真正好处。当然,这可能会带来性能损失,但通常你不必考虑它,除非你想编程,例如实时应用。正确使用 OOP 和 OOD 会使您的代码非常灵活并且(在某种程度上)易于理解。

    【讨论】:

      【解决方案4】:

      对此有用的设计模式是单例的变体。设置您的静态实现,保留静态方法 private,通过对象实例公开它们,如下所示:

      class MySingletonClass
      {
          //-----------------------------------------
          // here, we hide the static implementations
          //-----------------------------------------
          private static int privateFoo()
          {
              /* do something useful here */
          }
          private static string privateBar()
          {
              /* do something useful here */
          }
      
          //---------------------------------------
          // and expose them via an object instance
          //---------------------------------------
          public int Foo()
          {
              return privateFoo() ;
          }
          public string Bar()
          {
              return privateBar() ;
          }
      }
      

      您的静态类现在具有与普通对象实例相同的语义。这样调用静态方法:

      SomeStaticClass.SomeStaticMethod() ;
      

      虽然非静态类因此是引用:

      SomeNonStaticClass instance = new SomeNonStaticClass() ;
      instance.SomeNonStaticMethod() ;
      

      通过实例方法公开 [private] 静态方法,您隐藏了 对象用户的实现。那么,当你意识到这一点时 您的静态方法将不再起作用(无论出于何种原因),并且该类必须 变成非静态的,你所要做的就是修改类的内部实现。

      如果你的类的用户直接引用静态方法,你将不得不改变 代码库中的每个引用。

      【讨论】:

      • 一个方法是否是静态的表示正在执行的概念操作。这不仅仅是一些实现细节。如果您要更改方法的静态性,则表明从一开始就对该操作所代表的内容存在核心误解。以改变其核心原则而不引起破坏性更改为目的的代码设计将非常非常有用,因为任何时候你实际上犯了这个错误,你几乎肯定会遇到一大堆问题.你试图解决这个问题会造成更大的伤害。
      猜你喜欢
      • 2016-04-14
      • 1970-01-01
      • 1970-01-01
      • 2011-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-03
      相关资源
      最近更新 更多