One of the six principles of design pattern: DIP: Dependency Inversion Principle

definition

High level modules should not rely on low-level modules, and both should rely on their abstraction;
Abstractions should not rely on details;
Details should rely on abstraction.
In other words, high-level modules, low-level modules and details should rely on abstraction

1. What is the dependency inversion principle in C + +?
Definition of dependency inversion principle: it depends on abstraction (Interface) rather than specific implementation (class), that is, programming for interface.

2. An illustration of the principle of dependence inversion.

3. You need to know an important feature of C + +: high cohesion and low coupling. High cohesion, low coupling. High cohesion, low coupling.

origin

Class a directly depends on class B. If you want to change class B to class C, you must modify the code of class A.
Class A is generally a high-level module, which is responsible for complex business logic.
Class B and class C are low-level modules responsible for basic atomic operations.
Modifying class A will bring unnecessary risks to the program.

Solution

Modifying class A to rely on interface I, class B and class C implement interface I respectively, and class A is indirectly connected with class B or class C through interface I, which will greatly reduce the probability of modifying class A.

advantage

The dependency inversion principle can reduce the coupling between classes, improve the stability of the system, reduce the risk caused by parallel development, and improve the readability and maintainability of the code.

reflection

1. What is the relationship between dependency inversion principle and interface oriented programming?
The core idea of dependency inversion principle is interface oriented programming

2. What is detail? What is abstraction? What's the difference between them?
The so-called details are more specific things, such as specific classes, such as class B and class C above, with specific implementation.

The so-called abstraction is a contractual, common and normative expression, such as the above interface I. It expresses a contract - you need to implement funcA and funcB to be treated as I.

Compared with the variability of details, abstract things are much more stable.
Take the above class ABC as an example. Classes B and C belong to details. If a directly depends on B or C, the change of B or C may affect the stability of A. Similarly, the operation of a on B or C may also affect the stability of B or C. These interactions actually come from direct dependence, resulting in too much exposure of details of B or C. Facing the abstract interface I, a can only operate funA and funcB, thus avoiding unnecessary exposure and risk.

An architecture based on abstraction is much more stable than an architecture based on detail.
Stability is manifested in standardization, contract, easy modification, expansibility, maintainability and so on.

Attention

Distinguish detail from abstraction
Although the dependency inversion principle has great benefits, not all classes need an abstract interface to correspond, depending on the situation.

The declaration type of a variable should be an abstract class or interface
Attention is to try, not all.

Try not to override the methods of the base class
If the base class is an abstract class and this method has been implemented, subclasses should not be overridden as much as possible. Inter class dependencies are abstract. Overriding abstract methods will have a certain impact on the stability of dependencies.

Inheritance should follow the principle of Richter substitution

Example

We have learned about the specific methods of dependency inversion to solve the problem. Let's take a look at how we should implement it in a specific project from the perspective of C/C + +.
Let's look at the specific implementation of the code by telling me a story from a classic mother:
First, we define a storybook class, like this:

 #include <iostream>
 
using namespace std;
class Book
{
public:
	Book(){}
	~Book(){}
public:
	const std::string GetBookText()
	{
		return "once upon a time......";  //long time ago......
	}
};

Then our moms made a grand debut, like this:

class Monther
{
public:
	Monther(){}
	~Monther(){}
public:
	void readBook(Book& book)
	{
		std::cout << book.GetBookText() << std::endl;
	}
};

Then our mother began to tell us bedtime stories, like this:

int main(int argc, char *argv[])
{
    Book book;
	Monther* monther = new Monther();
	if(monther != nullptr)
	{
		monther->readBook(book);   //My mother told me a story and I slept well
	}
	delete monther;
	monther = NULL;
	return 0;
}

At this point, my mother's story is over, and I went to bed. However, suddenly one day, I don't want to listen to the story. I want to listen to the news, the radio and... Oh, it's a blessing for my mother to meet such a child, but we are filial children. We can design our code logic in this way. Pay attention, The real reliance on inverted design is on the stage, pay attention, pay attention, pay attention!!!
First, we abstract a parent interface of the base class for all books, like this:

class IReadContent 
{
public:
	IReadContent(){}
	virtual ~IReadContent(){}      //The destructor is defined as a virtual type to ensure that the derived class is completely destructed after inheritance
public:
	virtual const std::string GetContent() const = 0;   //Get the specific content of the readings
}

Then, I want to hear stories, news, and... Well,,,,, let storybooks and newspapers inherit this reading class, like this:

//Fairy tale town / * American drama. It's a very good call story play. You can go and have a look if you are interested*/
class StoryBook:public IReadContent     //Storybooks
{
public:
	virtual const std::string GetContent() const
	{
		return "Once upon a time, snow white and the dwarfs fought against each other in the magic forest......";
	}
};


//Newspaper
class NewsPager:public IReadContent
{
	virtual const std::string GetContent() const
	{
		return "The newspaper said that snow white and the dwarf lived happily in fairy tale town......";
	}
};

Our mother is on the stage again. Oh, why do you say "again"? My mother is very good this time. If you don't believe it, look:

class Monther
{
public:
	void read(IReadContent& readContent)
	{
		std::cout<< readContent.GetContent() << std::endl;
	}
};

It's time for mom to start telling stories again. Oh, no, mom can tell everything. Let's see the following decomposition:

int main(int argc, char *argv[])
{
	Monther* monther = new Monther();    //Define a great mother
	if(monther)
	{
		StoryBook storyBook;            //I want to hear stories
		monther->read(storyBook);     //Tell you a story

		NewsPager newsPager;        //I want to hear the news
		monther->read(newsPager);   //Tell you the news

       //... / / I want to hear               
       //... / / I'll tell you
       
		//... / / I want to hear
		//... / / why don't you go to heaven
	}
	
	delete monther;
	monther = NULL;
	return 0;
}
So far, mom's story is finished, and I begin to tell the story of dependency inversion. Well, mom is the top business logic layer (class) Monther),Of course, the interface layer is our intermediate hub reading class interface (class) IReadContent),The detail implementation layer when people don't let it be our several detail implementation classes( StoryBook,NewsPager ,Wait), looking back at our definition:**"High level modules should not rely on low-level modules, but on abstraction. Abstraction should not rely on details, details should rely on abstraction. "**If you don't understand, I suggest you listen to your mother's story again. If you don't understand, well, come to me. I'll tell you my mother's story slowly:"A long time ago... "

Data link:
https://www.jianshu.com/p/bb1d5a0c65d6

https://blog.csdn.net/weixin_39951988/article/details/85704400?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.no_search_link

Tags: Java C C++ mvc

Posted on Fri, 19 Nov 2021 06:44:30 -0500 by English Fire