I walk very slowly, but I never walk backwards
Copy the code
Design Pattern Principle – Single responsibility principle
Become as
Hello, everyone, I am silent ~, in this class, I will introduce the single responsibility principle of the design pattern principle, lead you to uncover the mystery of the design pattern principle, no more words, we enter the main topic. I don’t know if you have encountered the following situation
In the actual development process, sometimes you will find that their class is getting bigger and bigger, hundreds of thousands of lines, the class has more and more functions, some developers, including me before, see their class is big enough, enough functions, maybe a little proud, right, look, this is I wrote the country!! But when a function needs to make a small change, you will find that the whole program has all kinds of big and small problems, and then the hair becomes less and less….
How could a small change to a single feature of this class cause such a big problem? Is because we actually violated the single responsibility principle, integrate a variety of functions in a class, is equal to the functional coupling up, the change of a function could weaken or suppress this kind of ability to perform other duties, and if you want to avoid the occurrence of this phenomenon, as much as possible to comply with the single responsibility principle, the single responsibility principle is what?
Of course, let’s first look at the definition of the single responsibility principle
The official definition of
The Single Responsibility Principle (SRP), which has one and only one reason for class changes
Basic introduction
Based on the above definition, let’s make a basic introduction to the single responsibility principle
That is, for classes, a class should have only one responsibility. For example, class A is responsible for two different responsibilities: responsibility 1 and responsibility 2. When the requirements of responsibility 1 change and responsibility A changes, the execution of responsibility 2 May be wrong, so the granularity of class A needs to be decomposed into A1 and A2
What do you mean, give you an chestnuts, if you project a DAO layer in the class, both user table operation, operation order table, that is to say, the bean is responsible for the user to add and delete, and is responsible for the order table to add and delete, so this class is responsible for the two different responsibilities, is a violation of the single responsibility principle, So the principle is to break down the granularity of this class into a userDao that operates on the User table and an orderDao that operates on the ORDER table
Case study: Animal World
Now that you’ve heard about the single responsibility principle, let’s look at the following example
We have an animal class, which defines a method to run in the forest, and then we create an instance of the animal, call the method, and print within the method
public class SingleDemo { public static void main(String[] args) { Animal animal = new Animal(); Animal. The run (" tiger "); Animal. The run (" lion "); Animal. The run (" eagle "); Public void run(String Animal){system.out.println (Animal + "running in the forest "); }}Copy the code
First of all, there is no syntax problem in this code, but when you execute it, you can see that there is an obvious logical error, the eagle cannot run in the forest, in other words, in the run method, there is an animal in the forest, there is an animal in the sky, which violates the single responsibility principle
Solution 1: Break it down to smaller granularity
According to the principle of single responsibility, we can divide the original class Animal into multiple classes. Under the current business logic, each class is responsible for different responsibilities. Therefore, according to the above case, we can split the Animal class into different classes according to the position of running
public class SingleDemo { public static void main(String[] args) { ForestAnimal forestAnimal = new ForestAnimal(); ForestAnimal. Run (" tiger "); ForestAnimal. Run (" lion "); SkyAnimal skyAnimal = new SkyAnimal(); SkyAnimal. Fly (" eagle "); Public void run(String animal){system.out.println (animal + "im running in the forest "); }} public void fly(String animal){system.out.println (animal + "is flying in the sky "); }}Copy the code
OK, so first of all, it does follow the single responsibility principle, and it also keeps the business logic right, but at the same time, you have to think about it, it’s a big change, not only we have to break it down, but we also have to change the client in a big way.
So what else can we do?
Solution 2: Modify the original class
If you want to use solution 1, you not only need to break the class, but also need to modify the code in the client. Let’s look at a code example
public class SingleDemo { public static void main(String[] args) { Animal animal = new Animal(); Animal. RunForest (" tiger "); Animal. RunForest (" lion "); Animal. RunSky (" eagle "); }} public void runForest(String Animal) {system.out.println (Animal + "runForest "); } public void runSky(String animal) {system.out.println (animal + "is flying in the sky "); }}Copy the code
So let’s do an analysis for plan two
-
This modification method does not make major changes to the original class, but only adds methods
-
Client side changes are minimal and business logic is correct
Then some people may ask, so this way of writing, also the forest and the sky animal coupling in the same class ah?
Note that this is true, but scenario 2 does not adhere to the single responsibility principle at the class level, but at the method level, it does adhere to the single responsibility principle, that is, one method is responsible for one responsibility
From the above two schemes, we can see that scheme 1 and category level abide by the principle of single responsibility, but the cost of change is high; Scheme 2 and method level abide by the principle of single responsibility, but the change is small. To sum up, the core of the principle of single responsibility is actually each performing its own duties
Notes & details
-
Reduce the complexity of classes so that each class has only one responsibility
(With fewer responsibilities for a class, the corresponding complexity is reduced.)
-
Improve readability and maintainability of classes
(The corresponding reduction in complexity leads to less code, higher readability, and higher maintainability)
-
Reduce the risk of change
(The more responsibilities a class has, the greater the likelihood of change and the greater the risk of change.)
-
In general, we should adhere to the principle of single responsibility
(The single responsibility principle can be violated at the code level only if the logic is simple enough, and the single responsibility principle can be maintained at the method level only if the number of methods in the class is small enough, see Scenario 2)
How to comply with the single responsibility principle?
As mentioned in the above note, as one of the seven principles of design pattern, our code should generally adhere to the single responsibility principle, so we must have more or less such a question, how to comply?
In fact, it is a reasonable decomposition of responsibilities. The same responsibilities are put together and different responsibilities are decomposed into different interfaces and implementations. This is the easiest and most difficult principle to apply
It is important to note that the single responsibility principle is not unique to object-oriented programming but applies to modular programming
Next day forecast
The next section, we formally entering the interface segregation principle study of the principles of design patterns, I will for everyone to use multiple case studies, to interpret the interface segregation principle of design pattern principle, and its points for attention and detail, hope everyone in the process of learning, can feel interesting about design patterns, efficient and happy learning, the next time we see ~