官术网_书友最值得收藏!

Dependency inversion principle (DIP)

"High level modules should not depend on low level modules. Both should depend on abstractions. Abstractions should not depend upon details. Details should depend on abstractions"
                                                                                                             –Robert C. Martin

Have you ever found yourself standing in a shoe store wondering if you should get the brown or the black pair, only to get home and regret your choice? Sadly, once you've bought them, they're yours. Programming against concrete implementations is the same thing: once you choose, you are stuck with it, refunds and refactoring notwithstanding. But why choose when you don't have to? Look at the relationship shown in the following diagram:

Not very flexible, is it?  Let's convert the relationship into an abstraction:

That's much better. Everything relies only on nice clean abstractions, satisfying both LSP and ISP. The packages are concise and clear, happily satisfying the SRP. The code even seems to satisfy Robert C. Martin's description of the DIP, but sadly, it doesn't. It's that pesky word in the middle, inversion. 

In our example, the Shoes package owns the Shoe interface, which is entirely logical. However, problems arise when the requirements change. Changes to the Shoes package are likely to cause the Shoe interface to want to change. This will, in turn, require the Person object to change. Any new features that we add to the Shoe interface may be not be needed or relevant to the Person object. Therefore, the Person object is still coupled to the Shoe package.

In order to entirely break this coupling, we need to change the relationship from Person  uses Shoe to Person  requires Footwear, like this:

There are two key points here. Firstly, the DIP forces us to focus on the ownership of the abstractions. In our example, that means moving the interface into the package where it was used and changing the relationship from uses to requires; it's a subtle difference, but an important one.

Secondly, the DIP encourages us to decouple usage requirements from implementations. In our example, our Brown Shoes object implements Footwear, but it's not hard to imagine a lot more implementations and some might not even be shoes.

主站蜘蛛池模板: 兰州市| 凤城市| 扎赉特旗| 苏尼特左旗| 楚雄市| 尚义县| 拉萨市| 唐海县| 凉城县| 东港市| 邹平县| 贵港市| 安塞县| 迁西县| 永宁县| 哈巴河县| 阳谷县| 宁波市| 抚顺县| 凉山| 温泉县| 永宁县| 蓝山县| 阳西县| 玉环县| 无锡市| 伊金霍洛旗| 辽宁省| 江达县| 五大连池市| 西藏| 长沙市| 穆棱市| 镇远县| 商河县| 永新县| 两当县| 靖西县| 育儿| 贺兰县| 准格尔旗|