所谓依赖,指代码中的耦合。依赖倒置,是相对于传统的面向过程的设计结构而言,面向对象的结构把依赖关系倒置了。
DIP原则:
[b][size=large]高层模块不应该依赖于低层模块,二者都应该依赖于抽象[/size][/b]。高层模块只应该包含重要的业务模型和策略选择,低层模块则是不同业务和策略实现。首先高层模块和低层模块都要抽象出来,高层抽象不依赖于高层和低层模块的具体实现,最多只依赖于低层的抽象。高层的实现独立于低层模块不应该依赖于低层模块,而是依赖于低层抽象。同时,低层的抽象和实现也只依赖于高层的抽象.为什么要依赖于抽象呢?因为抽象/接口都是相对稳定的,不会被频繁改动的,依赖是可以信任的。如果都依赖于具体的实现,想想吧,改动一小块代码是多么的困难。试试吧,你会一再地品尝崩溃的感觉甚至开始厌恶软件开发。
[b][size=large]抽象不应该依赖于细节,细节应该依赖于抽象[/size][/b]。我想面向接口编程已经向大家证实了这个观点,不用过多的解释为什么了吧?难道你吃的亏还不够多!
一些辅助原则可以帮助你更好的运用DIP:
[list=1]
[*]任何变量都不应该持有一个指向具体类的引用。
[*]任何类都不应该从具体类派生。
[*]任何方法都不应该覆盖它的任何基类中已经实现了的方法。
[/list]重申一点:任何原则都不是绝对的。有些情况下上面三个原则都是可以违反的,只要你保持足够清醒。例如你依赖于String,我想不会有任何问题。
问题接着来了,如何抽象?
抽象反映高层策略,就是应用中那些不会随着具体细节的改变而改变的规则,常用的词语就是隐喻(metaphore).仔细分析需求,先找出那些业务规则,然后把它们抽象出来形成你的接口。层次化你的设计,常见的方式就是划分出显示层,业务层,持久层,再在每层做抽象。这是最粗糙的层次化,你可以在每层再根据需要划分更细的层次。在实现的时候始终遵循前面提到的原则:只依赖于接口。谁也无法在开始就做到最好,因此要不断迭代,精化设计。
推荐阅读:
[url=http://samuelray.iteye.com/blog/178463]开闭原则[/url]。
[url=http://samuelray.iteye.com/blog/172958]单一职责原则[/url]。
[url=http://samuelray.iteye.com/blog/170463]OO设计原则[/url]。
DIP原则:
[b][size=large]高层模块不应该依赖于低层模块,二者都应该依赖于抽象[/size][/b]。高层模块只应该包含重要的业务模型和策略选择,低层模块则是不同业务和策略实现。首先高层模块和低层模块都要抽象出来,高层抽象不依赖于高层和低层模块的具体实现,最多只依赖于低层的抽象。高层的实现独立于低层模块不应该依赖于低层模块,而是依赖于低层抽象。同时,低层的抽象和实现也只依赖于高层的抽象.为什么要依赖于抽象呢?因为抽象/接口都是相对稳定的,不会被频繁改动的,依赖是可以信任的。如果都依赖于具体的实现,想想吧,改动一小块代码是多么的困难。试试吧,你会一再地品尝崩溃的感觉甚至开始厌恶软件开发。
[b][size=large]抽象不应该依赖于细节,细节应该依赖于抽象[/size][/b]。我想面向接口编程已经向大家证实了这个观点,不用过多的解释为什么了吧?难道你吃的亏还不够多!
一些辅助原则可以帮助你更好的运用DIP:
[list=1]
[*]任何变量都不应该持有一个指向具体类的引用。
[*]任何类都不应该从具体类派生。
[*]任何方法都不应该覆盖它的任何基类中已经实现了的方法。
[/list]重申一点:任何原则都不是绝对的。有些情况下上面三个原则都是可以违反的,只要你保持足够清醒。例如你依赖于String,我想不会有任何问题。
问题接着来了,如何抽象?
抽象反映高层策略,就是应用中那些不会随着具体细节的改变而改变的规则,常用的词语就是隐喻(metaphore).仔细分析需求,先找出那些业务规则,然后把它们抽象出来形成你的接口。层次化你的设计,常见的方式就是划分出显示层,业务层,持久层,再在每层做抽象。这是最粗糙的层次化,你可以在每层再根据需要划分更细的层次。在实现的时候始终遵循前面提到的原则:只依赖于接口。谁也无法在开始就做到最好,因此要不断迭代,精化设计。
推荐阅读:
[url=http://samuelray.iteye.com/blog/178463]开闭原则[/url]。
[url=http://samuelray.iteye.com/blog/172958]单一职责原则[/url]。
[url=http://samuelray.iteye.com/blog/170463]OO设计原则[/url]。