Dependency inversion principle A. High-level modules should not be dependent on low levels of modules, they should all rely on abstraction. B. Abstractions should not be dependent on specifics, but should be dependent on abstraction. Dependency inversion principle A. High-level modules should not be dependent on low levels of modules, they should all rely on abstraction. B. Abstractions should not be dependent on specifics, but should be dependent on abstraction. Directory
-
1 overview
-
2 Intentions
-
3 Code implementation
-
4 structure diagram
1 Overview editing The so-called dependency inversion principle (dependence inversion Principle) is to rely on abstraction and not rely on specifics. Simply put, it requires programming the abstraction, not programming the implementation, which reduces the coupling between the customer and the implementation module.2 intention to edit Process-oriented development, the upper layer calls the lower layer, the upper layer relies on the lower layer, when the lower level of drastic changes in the upper layer also to follow the change, which will lead to the reduction of the module reusability and greatly improve the cost of development. Object-oriented development is a good solution to this problem, in general, the probability of abstract change is very small, so that the user program depends on the abstraction, the implementation of the details are also dependent on abstraction. Even if the implementation details are constantly changing, the client program does not need to change as long as the abstraction is constant. This greatly reduces the coupling between the client program and the implementation details. Structure diagram for process thinking: Figure 1: 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 the car, which can be used on Ford and Honda vehicles, as long as the two brands of cars use the system to achieve autonomous driving. So someone made an analysis of one. For graph One analysis: We define a Autosystem class, a Fordcar class, and a Hondacar class. There are three methods in the Fordcar class and the Hondacar class: Run (Start car), Turn (Turn car), stop (stop car), of course, a car certainly more than these features, as long as you can explain the problem. The Autosystem class is an autonomous driving system that automatically manipulates the two vehicles.3 Code implementation editing
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 6667686970717273 |
publicclassHondaCar{
publicvoidRun()
{
Console.WriteLine(
"本田开始启动了"
);
}
publicvoidTurn()
{
Console.WriteLine(
"本田开始转弯了"
);
}
publicvoidStop()
{
Console.WriteLine(
"本田开始停车了"
);
}
}
publicclassFordCar
{
publicvoidRun()
{
Console.WriteLine(
"福特开始启动了"
);
}
publicvoidTurn()
{
Console.WriteLine(
"福特开始转弯了"
);
}
publicvoidStop()
{
Console.WriteLine(
"福特开始停车了"
);
}
}
publicclassAutoSystem
{
publicenumCarType{Ford,Honda};
privateHondaCarhcar=newHondaCar();
privateFordCarfcar=newFordCar();
privateCarTypetype;
publicAutoSystem(CarTypetype)
{
this
.type=type;
}
privatevoidRunCar()
{
if
(type==CarType.Ford)
{
fcar.Run();
}
else
{
hcar.Run();
}
}
privatevoidTurnCar()
{
if
(type==CarType.Ford)
{
fcar.Turn();
}
else
{
hcar.Turn();
}
}
privatevoidStopCar()
{
if
(type==CarType.Ford)
{
fcar.Stop();
}
else
{
hcar.Stop();
}
}
}
|
Code Analysis: The above program does realize unmanned driving for Ford and Honda cars, but software is constantly changing and software needs are constantly changing. Background 2: The company's business is bigger, at the same time become a GM, Mitsubishi, Volkswagen's gold partner, so the company asked the automatic driving system can also be installed in the 3 kinds of companies to produce cars. So we have to change Autosystem:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
publicclassAutoSystem
{
publicenumCarType{Ford,Honda,Bmw};
HondaCarhcar=newHondaCar();
FordCarfcar=newFordCar();
BmwCarbcar=newBmwCar();
privateCarTypetype;
publicAutoSystem(CarTypetype)
{
this
.type=type;
}
privatevoidRunCar()
{
if
(type==CarType.Ford)
{
fcar.Run();
}
elseif(type==CarType.Honda)
{
hcar.Run();
}
elseif(type==CarType.Bmw)
{
bcar.Run();
}
}
privatevoidTurnCar()
{
if
(type==CarType.Ford)
{
fcar.Turn();
}
elseif(type==CarType.Honda)
{
hcar.Turn();
}
elseif(type==CarType.Bmw)
{
bcar.Turn();
}
}
privatevoidStopCar()
{
if
(type==CarType.Ford)
{
fcar.Stop();
}
elseif(type==CarType.Honda)
{
hcar.Stop();
}
elseif(type==CarType.Bmw)
{
bcar.Stop();
}
}
}
|
Analysis: This will add new interdependence to the system. Over time, more and more vehicles must be added to the Autosystem, the "Autosystem" module will be confused by if/else statements, and rely on a lot of low-level modules, as long as the low-level module changes, Autosystem must follow the change, It will eventually become rigid and fragile. One reason for the problem described above is that a module that contains high-level policies, such as the Autosystem module, relies on modules (such as Hondacar () and Fordcar ()) that are specific to the lower levels that it controls. If we can find a way to make the Autosystem module independent of the specific details it controls, then we are free to reuse it. We can use this module to generate other programs so that the system can be used in the cars that are needed. Ood provides us with a mechanism to implement this "dependency inversion".4 structure diagram editing Figure two looks at this simple class diagram in Figure 2. Here is a "Autosystem" class that contains a "ICar" interface. This "Autosystem" class does not depend on "Fordcar" and "Hondacar" at all. Therefore, the dependency is "inverted": The "Autosystem" module relies on abstraction, and those specific car operations also rely on the same abstraction. You can then add icar
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 666768697071 |
publicinterfaceICar
{
voidRun();
voidTurn();
voidStop();
}
publicclassBmwCar:ICar
{
publicvoidRun()
{
Console.WriteLine(
"宝马开始启动了"
);
}
publicvoidTurn()
{
Console.WriteLine(
"宝马开始转弯了"
);
}
publicvoidStop()
{
Console.WriteLine(
"宝马开始停车了"
);
}
}
publicclassFordCar:ICar
{
publicvoidRun()
{
Console.WriteLine(
"福特开始启动了"
);
}
publicvoidTurn()
{
Console.WriteLine(
"福特开始转弯了"
);
}
publicvoidStop()
{
Console.WriteLine(
"福特开始停车了"
);
}
}
publicclassHondaCar:ICar
{
publicvoidRun()
{
Console.WriteLine(
"本田开始启动了"
);
}
publicvoidTurn()
{
Console.WriteLine(
"本田开始转弯了"
);
}
publicvoidStop()
{
Console.WriteLine(
"本田开始停车了"
);
}
}
publicclassAutoSystem
{
privateICaricar;
publicAutoSystem(ICaricar)
{
this
.icar=icar;
}
privatevoidRunCar()
{
icar.Run();
}
privatevoidTurnCar()
{
icar.Turn();
}
privatevoidStopCar()
{
icar.Stop();
}
}
|
Now the Autosystem system relies on the abstraction of icar, which has nothing to do with the specific implementation details Hondacar, Fordcar, Bmwcar, so the changes to the implementation details will not affect Autosystem. For implementation details as long as the implementation of ICAR, that is, implementation details rely on icar abstraction. In summary: An important strategic decision and business model in an application is in these high-level modules. It is also these models that contain the characteristics of the application. However, when these modules are dependent on low-level modules, modifications to the lower-level modules will directly affect them, forcing them to change as well. This kind of situation is absurd. Should be a high-level module to force those low-rise modules to change. Modules that are at the top of the module should take precedence over the lower level. At any rate, high-level modules should not be dependent on lower modules. Moreover, we want to be able to reuse a high-level module. In the form of a sub-library, we have been able to reuse the lower-level modules well. These high-level modules are difficult to reuse in different environments when high-level modules rely on lower-layer modules. However, when those high-rise modules are independent of the lower-level modules, they can be easily reused. This is the principle that is at the core of the design of the framework. Summary: Dependency inversion principle A. High-level modules should not be dependent on low levels of modules, they should all rely on abstraction. B. Abstractions should not be dependent on specifics, but should be dependent on abstraction.