Blog

Blog

PHODAL

dip 依赖倒置原则小试

DIP

依赖倒置原则(Dependence Inversion Principle)
High level modules should depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.
  • 高层模块不依赖于低层模块,两者都应该依赖于抽象。
  • 抽象不应该依赖于细节(具体实现类),细节(具体实现类)应该依赖于抽象。

依赖倒置原则是实现许多面向对象技术所宣称的好处的基本低层机制。

引用书中的例子

Simple Modern

Button类直接依赖于AILamp类

于是有一天类爆发了。


  var SmartLamp = function( ) {
    this.name = "SmartLamp";
    this.TurnOn = function( ) {
      print("Smart Lamp Turn On");
    };
    this.TurnOff = function( ) {
      print ("Smart Lamp Turn Off");
    };
  };

  var AILamp = function( ) {
    this.name = "AILamp";
    this.TurnOn = function( ) {
      print("AI Lamp Turn On");
      };
    this.TurnOff = function( ) {
      print("AI Lamp Turn Off");
      };
  };
  var FutureLamp = function() {
    this.name = "FutureLamp";
    this.Turnon = function() {
      print("Future Lamp Turn On");
      };
    this.TurnOff = function() {
      print("Future Lamp Turn Off");
      };
   };
  var AutoLamp = function(name ) {
    this.name=name;
    var ailamp = new AILamp();
    var smartlamp = new SmartLamp();
    var futurelamp = new FutureLamp();
    this.TurnOn = function(name) {
      if(this.name === ailamp.name) {
        ailamp.TurnOn();
        }else if(this.name === smartlamp.name){
            smartlamp.TurnOn();
          }else if(this.name === futurelamp.name){
            futurelamp.TurnOff();
            }
      };
    this.TurnOff = function (name) {
      if(this.name === ailamp.name) {
        ailamp.TurnOff();
        }else if(this.name === smartlamp.name){
            smartlamp.TurnOff();
          }else if(this.name === futurelamp.name){
            futurelamp.TurnOff();
            }
      };
  };
  var lamp=new AutoLamp("FutureLamp");
  lamp.TurnOn();
  lamp.TurnOff();
应用程序的高层策略没有和低层实现分离

DIP System Modern

High Level Classes(高层模块)--> Abstraction Layer(抽象接口层) --> Low Level Classes(低层模块)

用javascript来说这个可能不是很适合,或许是个错误,但是在这里只是用来表达自己的想法,语言本身可能就是这样一个载体 。


    var Lamp = function(name) {
      this.name = name;
      this.TurnOn = function() {
        print(name+" Turn On");
        };
      this.TurnOff = function() {
        print(name+" Turn Off");
        };
    };
    var AILamp = function() {
      this.name = "AI Lamp";
      Lamp.call(this,this.name);
    };
    var SmartLamp = function() {
      this.name = "Smart Lamp";
      Lamp.call(this,this.name);
    };
    var FutureLamp = function(){
      this.name = "Future Lamp";
      Lamp.call(this,this.name);
    };
    var AutoLamp = function(Lamp){
      var lamp = new Lamp();
      this.TurnOn = function() {
        lamp.TurnOn();
        };
      this.TurnOff = function() {
        lamp.TurnOff();
        };
    };
    var newlamp = new AutoLamp(SmartLamp);
    newlamp.TurnOn();
    var lamp2 = new AutoLamp(AILamp);
    lamp2.TurnOff();

依赖于抽象

启发性规则

  • 任何变量都不应该持有一个指向具体类的指针或者引用
  • 任何类都不应该从具体类派生
  • 任何方法都不应该覆写它的任何基类中的已经实现了的方法

依赖关系倒置

将Lamp作成Abstract,然后具体类继承自Lamp

DIP System Modern

  • 构造器注入
  • 属性注入
  • 方法注入

多态是实现DIP的必要条件

这点是值得去注意的在这样一个个的概念之后,上面的代码示例就是为了说明这样一个事实。

要针对接口编程,不要对实现编程(Program to aninterface, not an implementation)


或许您还需要下面的文章:

关于我

Github: @phodal     微博:@phodal     知乎:@phodal    

微信公众号(Phodal)

围观我的Github Idea墙, 也许,你会遇到心仪的项目

QQ技术交流群: 321689806
comment

Feeds

RSS / Atom

最近文章

关于作者

Phodal Huang

Engineer, Consultant, Writer, Designer

ThoughtWorks 技术专家

工程师 / 咨询师 / 作家 / 设计学徒

开源深度爱好者

出版有《前端架构:从入门到微前端》、《自己动手设计物联网》、《全栈应用开发:精益实践》

联系我: h@phodal.com

微信公众号: 最新技术分享

标签