What
Dependence inversion Principle (DIP): High-level modules should not rely on the underlying module, should be dependent on the abstraction, the abstraction should not depend on the specific, depending on the abstract
Why
If the upper level relies on the bottom layer, then the underlying changes will also lead to high-level changes, which will lead to reduced reusability of the module and greatly improve the cost of development. If it is dependent on abstraction, then it is relatively stable, and the changes at the bottom or the top will not affect each other.
How
A very representative example of the individuals cited in many places is that the company is a gold partner for Ford and Honda, and now requires the development of an autonomous driving system that can be unmanned if the system is installed on a car, which can be used on Ford and Honda vehicles, As long as these two brands of cars use the system can achieve automatic driving.
Ford Motor class, contains three methods, start, stop, turn
classFordcar { Public voidRun () {Console.WriteLine ("Fordcar Run"); } Public voidStop () {Console.WriteLine ("Fordcar Stop"); } Public voidTurn () {Console.WriteLine ("Fordcar Turn"); } }
HTC Car class, contains three methods, start, stop, turn
classHondacar { Public voidRun () {Console.WriteLine ("Hondacar Run"); } Public voidStop () {Console.WriteLine ("Hondacar Stop"); } Public voidTurn () {Console.WriteLine ("Hondacar Turn"); } }
Autopilot system with three ways to start a car, stop a car, turn a car
classAutosystem {hondacar Hondacar=NewHondacar (); Fordcar Fordcar=NewFordcar (); Cartype type; PublicAutosystem (cartype type) { This. Type =type; } Public voidRuncar () {if(Type = =Cartype.honda) {hondacar.run (); } Else if(Type = =Cartype.ford) {fordcar.run (); } } Public voidStopcar () {if(Type = =Cartype.honda) {hondacar.stop (); } Else if(Type = =Cartype.ford) {fordcar.stop (); } } Public voidTurncar () {if(Type = =Cartype.honda) {Hondacar.turn (); } Else if(Type = =Cartype.ford) {Fordcar.turn (); } } }
At present, is to meet the demand, but with the development of business is also developing, now if the development of partners, the need for other brands of cars to add automatic driving system, such as red Flag, Chery and other brands, then if the previous way, you need to modify the Autosystem, first add two new brand car objects, Then in the start of the car, stop the car, the car steering changes to add branch statements to different brands to judge and then add a variety of operations, so that the breach of the OCP, and complex branch statements will be prone to error, if you continue to expand the other brand, then such a program is not easy to maintain, The robustness of the program is poor, greatly increasing the cost of development. So sensitive classmates have seen, since the different car brands have the same behavior, then why not define an interface? Now that we define an interface and then implement this interface for each brand of car, we can operate on the defined interface in Autosystem.
Interface ICar { void Run (); void Stop (); void Turn (); }
Autopilot system is the high-level module is now for this abstract interface, no matter what the car, as long as the implementation of the ICAR interface, you can do related operations.
class Autosystem { ICar car; Public Autosystem (ICar car) { this. Car = car; } Public void Runcar () { car. Run (); } Public void Stopcar () { car. Stop (); } Public void Turncar () { car. Turn (); } }
The Ford Motor class is also the bottom module, which implements the Icar interface, and now relies on an abstract interface.
classFordcar:icar { Public voidRun () {Console.WriteLine ("Fordcar Run"); } Public voidStop () {Console.WriteLine ("Fordcar Stop"); } Public voidTurn () {Console.WriteLine ("Fordcar Turn"); } }
The HTC Car class is also the bottom module, realizes the Icar interface, now relies on the abstract interface
classHondacar:icar { Public voidRun () {Console.WriteLine ("Hondacar Run"); } Public voidStop () {Console.WriteLine ("Hondacar Stop"); } Public voidTurn () {Console.WriteLine ("Hondacar Turn"); } }
When high-level modules rely on the bottom, then the high-level reusability is poor, as the above example said to increase the car brand category. If the upper and lower layers are dependent on the abstraction, then the high-level reusability is better, because through the inheritance of the interface to achieve polymorphism, then reuse more places, so the design is undoubtedly more stable.
Dependency Inversion principle