Skip to main content

创建类的时候注意的原则SOLID

避免使用单例模式

单例模式是一种反模式。为什么不建议使用:

他们通常使用一个全局实例,为什么这么糟糕?因为你隐藏了依赖关系在你的项目的代码中,而不是通过接口暴露出来。你应该有意识的去避免那些全局的东西。

他们违背了单一职责原则:他们会自己控制自己的生命周期。

这种模式会自然而然的使代码耦合在一起。这会让他们在测试中,很多情况下都理所当然的不一致。 他们持续在整个项目的生命周期中。另外一个严重的打击是当你需要排序测试的时候,在单元测试中这会是一个不小的麻烦。为什么?因为每个单元测试都应该依赖于另外一个。

SOLID

SOLID 最开始是由 Robert Martin 提出的五个准则,并最后由 Michael Feathers 命名的简写,这五个是在面对对象设计中的五个基本原则。

S: 职责单一原则 (SRP) O: 开闭原则 (OCP) L: 里氏替换原则 (LSP) I: 接口隔离原则 (ISP) D: 依赖反转原则 (DIP)

  • 职责单一原则 (SRP)
    正如 Clean Code 所述,“修改类应该只有一个理由”。我们总是喜欢在类中写入太多的方法,就像你在飞机上塞满你的行李箱。在这种情况下你的类没有高内聚的概念并且留下了很多可以修改的理由。尽可能的减少你需要去修改类的时间是非常重要的。如果在你的单个类中有太多的方法并且你经常修改的话,那么如果其他代码库中有引入这样的模块的话会非常难以理解。
  • 开闭原则 (OCP)
    正如 Bertrand Meyer 所说,“软件开发应该对扩展开发,对修改关闭。” 这是什么意思呢?这个原则的意思大概就是说你应该允许其他人在不修改已经存在的功能的情况下去增加新功能。

  • 里氏替换原则 (LSP)
    这本身是一个非常简单的原则却起了一个不太容易理解的名字。这个原则通常的定义是 “如果 S 是 T 的一个子类,那么对象 T 可以在没有任何警告的情况下被他的子类替换(例如:对象 S 可能代替对象 T)一些更合适的属性。” 好像更难理解了。

    最好的解释就是说如果你有一个父类和子类,那么你的父类和子类可以在原来的基础上任意交换。这个可能还是难以理解,我们举一个正方形 - 长方形的例子吧。在数学中,一个矩形属于长方形,但是如果在你的模型中通过继承使用了 “is-a” 的关系就不对了。

  • 接口隔离原则 (ISP)
    ISP 的意思就是说 “使用者不应该强制使用它不需要的接口”。

    当一个类需要大量的设置是一个不错的例子去解释这个原则。为了方便去调用这个接口需要做大量的设置,但是大多数情况下是不需要的。强制让他们使用这些设置会让整个接口显得臃肿。

  • 依赖反转原则 (DIP) 这个原则有两个需要注意的地方:

    1. 高阶模块不能依赖于低阶模块。他们都应该依赖于抽象。
    2. 抽象不应该依赖于实现,实现应该依赖于抽象。 第一点可能有点难以理解,但是如果你有使用过像 Symfony 的 PHP 框架,你应该有见到过依赖注入这样的原则的实现。尽管他们是不一样的概念,DIP 让高阶模块从我们所知道的低阶模块中分离出去。可以通过 DI 这种方式实现。一个巨大的好处在于它解耦了不同的模块。耦合是一个非常不好的开发模式,因为它会让你的代码难以重构。