zoukankan      html  css  js  c++  java
  • 连载:面向对象葵花宝典:思想、技巧与实践(34)

    DIP,dependency inversion principle,中文翻译为“依赖倒置原则”。

     

    DIP是大名鼎鼎的Martin大师提出来的。他在1996 5月的C++ Reporter发表“ The Dependency Inversion Principle”的文章具体阐述了DIP原则,而且在他的经典著作《 Agile Software Development, Principles, Patterns》(中文翻译为:敏捷软件开发:原则、模式与实践)、《Practices, and Agile Principles, Patterns, and Practices in C#》(中文翻译为:敏捷软件开发:原则、模式与实践(C#版))中详解了DIP原则。

     

    DIP原则主要有两点含义:

    1) 高层模块不应该直接依赖低层模块。两者都应该依赖抽象层。

    2) 抽象不能依赖细节。细节必须依赖抽象。

     

    尽管DIP原则的解释很清楚。但要真正理解也不那么简单,由于有几个关键的术语都比較抽象,我们须要更具体的解析:

    1)什么是模块?

    英文中用到了module、component,但我们这是在讲类的设计原则,为什么要把DIP拉进来呢?

    事实上Martin大师仅仅是讲一个设计原则而已,这个原则能够应用到软件系统不同的层级。

    比如:站在架构层的角度,模块能够指子系统subsystem

    站在子系统的角度。模块能够指module,component

    站在模块的角度:模块能够指类

    所以说。这里的模块应该是一个广义的概念,而不是狭义的软件系统里各个子模块。

     

    2)什么是依赖?

    这里的依赖相应到具体的面向对象领域事实上包括几个内容:

    高层模块“依赖”低层模块:指高层模块须要调用低层模块的方法。

    高层模块依赖抽象层:指高层模块基于抽象层编程;

    低层模块依赖抽象层:指低层模块继承(inheritance)或者实现(implementation)抽象层。

    细节依赖抽象:事实上和上一个依赖是同一个意思;


    所以说,大师就是大师啊,一个简简单单的“依赖”将各种情况都概括进来了,仅仅是苦了我们这些平庸人,要么导致无法理解,要么导致理解错误:(

     

    我们以一个简单例子来详解这些依赖,例子包括一个Player类,代表玩家。ICar接口。代表汽车;Benz、Ford、Chery代表具体的汽车,具体的代码例如以下

    Player

    package com.oo.oop.dip;
    
    /**
     * 玩家,相应DIP中的“高层模块” 
     *
     */
    public class Player {
    
    	/**
    	 * 开福特
    	 * 不好的依赖:相应DIP中的“高层模块依赖低层模块”,Player直接使用了Ford类对象作为參数,Ford类改动,Player类【须要】又一次编译測试
    	 */
    	public void play(Ford car)
    	{
    		car.accelerate();
    		car.shift();
    		car.steer();
    		car.brake();
    	}
    	
    	/**
    	 * 开奔驰
    	 * 不好的依赖:相应DIP中的“高层模块依赖低层模块”。Player直接使用了Benz类对象作为參数。Benz类改动,Player类【须要】又一次编译測试
    	 */
    	public void play(Benz car)
    	{
    		car.accelerate();
    		car.shift();
    		car.steer();
    		car.brake();
    	}
    	
    	/**
    	 * 开奇瑞
    	 * 不好的依赖:相应DIP中的“高层模块依赖低层模块”,Player直接使用了Chery类对象作为參数,Chery类改动。Player类【须要】又一次编译測试
    	 */
    	public void play(Chery car)
    	{
    		car.accelerate();
    		car.shift();
    		car.steer();
    		car.brake();
    	}
    	
    	/**
    	 * 开车
    	 * 好的依赖: 相应DIP中的“高层模块依赖抽象层”,Player依赖ICar接口。不须要知道具体的车类型。Ford、Benz、Chery类改动。Player类【不须要】又一次编译測试。仅仅有ICar改动的时候Player才须要改动
    	 */
    	public void play(ICar car)
    	{
    		car.accelerate();
    		car.shift();
    		car.steer();
    		car.brake();
    	}
    
    }
    

    ICar

    package com.oo.oop.dip;
    
    /**
     * 汽车接口,相应DIP中的抽象层
     */
    public interface ICar {
    
    	/**
    	 * 加速
    	 */
    	public void accelerate();
    	
    	/**
    	 * 换挡
    	 */
    	public void shift();
    	
    	/**
    	 * 转向
    	 */
    	public void steer();
    	
    	/**
    	 * 刹车
    	 */
    	public void brake();
    }
    

    Benz

    package com.oo.oop.dip;
    
    /**
     * 奔驰,实现了ICar接口,相应DIP中的“低层依赖抽象层” 
     *
     */
    public class Benz implements ICar {
    
    	@Override
    	public void accelerate() {
    		
    		//加速很快
    		System.out.println("Benz accelerate: very fast !!"); 
    	}
    
    	@Override
    	public void shift() {
    		
    		//自己主动挡
    		System.out.println("Benz shift:  automatic transmission !!"); 
    	}
    
    	@Override
    	public void steer() {
    
    		//很平稳
    		System.out.println("Benz steer:  very smooth,ESP && DSC && VSC !!"); 
    	}
    
    	@Override
    	public void brake() {
    		
    		//刹车辅助系统
    		System.out.println("Benz steer:  ABS && EBA && BAS && BA !!"); 
    	}
    
    }
    

    Ford

    package com.oo.oop.dip;
    
    /**
     * 福特,实现了ICar接口,相应DIP中的“低层依赖抽象层” 
     *
     */
    public class Ford implements ICar {
    
    	@Override
    	public void accelerate() {
    		
    		//加速快
    		System.out.println("Ford accelerate: fast !!"); 
    	}
    
    	@Override
    	public void shift() {
    		
    		//手自一体变速器
    		System.out.println("Ford shift:  Tiptronic transmission !!"); 
    	}
    
    	@Override
    	public void steer() {
    
    		//平稳
    		System.out.println("Ford steer:  smooth。ESP !!"); 
    	}
    
    	@Override
    	public void brake() {
    
    		//刹车辅助系统
    		System.out.println("Ford steer:  ABS && EBA &!!"); 
    	}
    
    }
    

    Chery

    package com.oo.oop.dip;
    
    /**
     * 奇瑞。实现了ICar接口,相应DIP中的“低层依赖抽象层” 
     *
     */
    public class Chery implements ICar {
    
    	@Override
    	public void accelerate() {
    		
    		//加速慢
    		System.out.println("Chery accelerate: slow !!"); 
    	}
    
    	@Override
    	public void shift() {
    		
    		//手动挡
    		System.out.println("Chery shift:  manual transmission !!"); 
    	}
    
    	@Override
    	public void steer() {
    
    		//平稳
    		System.out.println("Chery steer:  smooth。ESP && DSC !!"); 
    	}
    
    	@Override
    	public void brake() {
    		
    		//刹车辅助系统
    		System.out.println("Chery steer:  only ABS !!"); 
    	}
    
    }


    ================================================ 

    转载请注明出处:http://blog.csdn.net/yunhua_lee/article/details/30749311
    ================================================ 


  • 相关阅读:
    【Delphi】MD5算法(二):应用
    迅雷不能下载FlashPlayer,下载后自动删除,狂汗!!!
    工作笔记1
    GridControl 获取筛选后的数据{笔记}
    Invoke与BeginInvoke[转]
    这几项能力不知道要几年
    你永远不要去做的事1【译】
    window环境变量——心得【转】
    刚做好的网站客服系统,欢迎大家测试
    .Net 2.0里有一个有用的新功能:迭代器
  • 原文地址:https://www.cnblogs.com/yfceshi/p/6905107.html
Copyright © 2011-2022 走看看