开放/封闭原则与依赖性倒置原则有什么区别?

时间:2013-08-25 10:29:03

标签: oop design-patterns solid-principles open-closed-principle dependency-inversion

DIP声明:

  
      
  • 高级模块不应依赖于低级模块。两者都应该取决于抽象。
  •   
  • 抽象不应该依赖于细节。细节应取决于抽象。
  •   

OCP声明:

  

软件实体(类,模块,函数等)应该是开放的   用于扩展,但已关闭以进行修改。

我认为如果我们满足DIP,它也将覆盖OCP,那么,为什么我们将这两个原则分开呢?

4 个答案:

答案 0 :(得分:5)

DIP告诉您 如何组织依赖项。它没有告诉你何时你完成了特定的界面。

粗略地说,OCP的信息是拥有完整但简约的界面。换句话说,它告诉你何时你完成了一个界面,但它没有告诉你如何来实现这一点。

在某种意义上,DIP和OCP是正交的。


  

那么,为什么我们将这两个原则分开呢?

至于设计模式和命名原则,几乎所有这些原则都有:

  1. 查找不同的内容并将其封装(隐藏)。

  2. 首选聚合继承。

  3. 设计接口。

  4. 即使指定的模式和原则在某种意义上部分重叠,它们也会告诉你比上述三个一般原则更具体的(在更具体的情况下)。

答案 1 :(得分:4)

我认为遵守DIP原则可以更容易地遵守OCP原则。但是,一方不保证另一方。

例如,我可以创建一个具有参数Base的方法的类。如果base是一个抽象类,那么我正在坚持DIP,因为我已将依赖关系转换为调用者。但是,如果该方法中的代码执行类似的操作:

if (base is derived)
    (derived)base.DoSomethingSpecificToDerived;
elsif (base is evenMoreDerived)
    (evenMoreDerived)base.DoSomethingSpecificToEvenMoreDerived;

然后它不符合OCP标准,因为每次添加新衍生产品时我都必须对其进行修改。

这是一个非常人为的例子,但你明白了我的观点。

答案 2 :(得分:0)

OCP使依赖类易于使用。 OCP通过将旧实现与较新版本分离来实现接口的异步使用。即使面对其他目的的变化,它也允许依赖它的东西继续依赖它。这样一个班级就不必关心谁在呼唤它。

DIP做了两件事。它使得依赖外部类很容易。依赖注入通过鼓励创建职责与消费分离来实现依赖性的替换。该模式不是创建要使用的外部依赖项,而是声明它应该在外部提供。最终,这会鼓励幂等的代码(不改变外部状态的代码)。幂等代码很好,因为可以验证它只能立即显示。它没有外部副作用。它非常可测试,可理解且易读。

答案 3 :(得分:0)

鲍勃·马丁叔叔将开放-封闭原则(OCP)和依赖倒置原则(DIP)推广为SOLID原则中的两项,states himself认为DIP源于OCP和Liskov替代原则的应用:

  

在本专栏中,我们讨论OCP和   LSP。严格使用这些结构的结构   原则本身可以概括为一个原则。我打电话   它是“依赖倒置原则”(DIP)。

     

Robert C. Martin,工程笔记本,C ++报告,1996年。

因此,您正确地指出DIP的每个实例都是OCP的实例,但是OCP更为通用。这是OCP的用例,但不是我最近遇到的DIP。许多Web框架都有信号的概念,一旦执行一项操作,就会触发信号。发送信号的对象完全不知道向该信号注册的侦听器。每次您想向信号添加更多的侦听器时,都可以这样做,而无需修改发送者。

这显然是OCP(“封闭修改,开放扩展”)的示例,而不是DIP,因为发件人不依赖任何东西,因此谈论它是否依赖于更抽象或更抽象的东西没有意义。 。

通常,您可以说观察者模式(GoF patterns之一)描述了如何遵守OCP而不是DIP。仔细阅读GoF书,看看哪些与OCP有关,以及哪些与DIP不相关,这很有趣。