O In programming, SOLID (single function, Open/close principle, Ridgeway substitution, interface isolation, and dependency inversion) is a mnemonic acronym introduced by Robert C. Martin in the early 21st century, referring to the five basic principles of object-oriented programming and object-oriented design. When applied together, these principles make it more likely that a programmer will develop a system that is easy to maintain and extend, and are typically applied in test-driven development, and are an important part of the basic principles of agile and adaptive software development.
S Single function principle: The single function principle states that an object should have only one concept of a single function.
O Open closed Principle: The open closed principle states the concept that the software body should be open for extension, but closed for modification.
Richter’s Substitution principle: The concept that an object in a program should be substitutable by its subclasses without changing the correctness of the program.
I Interface isolation principle: The interface isolation principle recognizes the concept that multiple specific client interfaces are better than one general-purpose interface.
I Interface isolation principle: The interface isolation principle recognizes the concept that multiple specific client interfaces are better than one general-purpose interface.
D Dependency inversion principle: The dependency inversion principle states that a method should follow the concept of “relying on an abstraction rather than an instance”. Dependency injection is an implementation of this principle.
Discussion of the single function principle
THERE SHOULD NEVER BE MORE THAN ONE REASON FOR A CLASS TO CHANGE. In other words, let a class do only one type of responsibility, and when that class needs to take on other types of responsibility, it needs to be broken up. Of all the SOLID principles, this is the one most developers feel most fully understand. Strictly speaking, this is probably the most frequently violated rule of all. The principle of single responsibility can be regarded as the extension of low coupling and high cohesion to the object oriented principle. Responsibility is defined as the cause of change, and the cause of change can be reduced by improving cohesion. Too much responsibility will lead to more reasons for its change, which will lead to responsibility dependence and influence each other, thus greatly damaging its cohesion and coupling degree. Single responsibility usually means single function, so do not implement too many function points for a module to ensure that the entity has only one cause for its change.
Application of this principle:
(1) Unix/Linux is the perfect embodiment of this principle. Each program is independently responsible for a single thing.
(2) Windows is an example of this principle in reverse. Almost all programs are intertwined and coupled together.
(3) Here’s another example: The format of the report and the content of the report will change, but both the different nature of change, one is the real inner, one is on the surface, SRP think it is a problem of two aspects, actually represent different responsibility, should be separated into different classes or modules, and should not put together, otherwise, the changes and for different reasons, Changes, such as a new report format, should not be related to the content.
Discussion of the open close principle
(1) Software entities should be extensible, not modifiable. That is, open for extension and closed for modification. This principle is one of the most abstract and difficult to understand of object-oriented programming principles. (2) Open to extension means that existing code can be extended to adapt to new situations when there are new requirements or changes.
(3) Closed to changes, meaning that once the class is designed, it can do its work independently without making any changes to the class.
(4) Change and change can be used to illustrate: encapsulate the invariable part, open the changing part, generally use the interface inheritance implementation way to achieve “open” to cope with the change, say plain words is: you don’t want to change? So I’m going to let you inherit an implementation object, abstracting your responsibilities with an interface, and the more you change, the more you subclass that implementation.
(5) The point of OCP is that, as developers, base classes are occasionally provided to us, and base class frameworks are occasionally generated for other developers to use. These consumers should only be able to use these base classes, but not modify them. This is necessary because other consumers may also rely on the functionality provided by the base class. Allowing consumers to modify these base classes can cause a ripple effect that affects not only aspects of the application sequence, but also applications within the enterprise. Another problem is that consumers may sometimes receive upgraded versions of base classes. Before upgrading, consumers must find a way to handle the customizations they made in previous versions of the base class.
The question then becomes, “So, what if I need to change the way this base class works?” Another part of the OCP gives this answer; Base classes should be open for extension. In this context, extending means creating a derived class that extends or overrides the functionality of the base class to provide the specific functionality required by the consumer. In this way, a consumer can use a modified version of the class without affecting other users of the class. Consumers can also use upgraded versions of base classes more easily in the future because they don’t have to worry about losing their changes.
Application of this principle:
For object orientation, you need to rely on abstraction, not implementation, and the “strategy pattern” in the 23 classic design patterns is this implementation. For non-object-oriented programming, some apis require you to pass in a function that you can extend, such as qsort() in our C language, which allows you to provide a “comparator”, memory allocation for container classes in the STL, and various locks for multithreading in ACE. On the software side, browser plug-ins are an exercise in this principle.
Discussion on Richter’s substitution principle
(1) Robert C. Martin, a software engineer, ultimately simplified the Reefer’s substitution principle into a sentence: “Subtypes must be substitutable for their base types”. That is, subclasses must be able to be replaced by their base class. That is, subclasses should be able to replace any base class that can occur, and the code should still work after the substitution. Also, there should be no if/else conditions for subclass types in your code. The Richter substitution principle LSP is an important guarantee for code compliance with the open and closed principle. It is the substitutability of subtypes that allows superclass modules to be extended without modification. In many cases, the relationships between our classes are not clear at the beginning of the design. LSP gives us a baseline for determining and designing relationships between classes: whether or not to inherit, and how to design inheritance relationships.
(2) A subclass has an IS-A relationship only when instances of it should be able to replace any instances of its superclass. Inheritance is to OCP what polymorphism is to The Richter’s substitution principle. Subclasses can replace base classes, which customers use without knowing what derived classes do. This is a principle of replaceable responsibility for behavior. If S is a subtype of T, then S objects should replace all T objects without changing any abstract properties.
Interface Isolation Principle
(1) Users should not be forced to rely on interfaces they do not use. In other words, it is better to have multiple specialized interfaces than a single master interface. Note: Applying an ISP to your code does not necessarily mean that the service is completely secure. Good coding practices are still required to ensure proper authentication and authorization.
(2) This principle originated from Xerox Corporation, which needed to establish a new printer system, which could perform a variety of tasks such as binding a set of printed matter and faxing. The system software is created from the bottom of the system, and realized these task functions, but the growing software functions make the software itself more and more difficult to adapt to change and maintenance. For every change, even the smallest change, someone might need nearly an hour to recompile and redeploy. It was almost impossible to develop further, so they hired Robert Robert to help them. They started by designing a main class, Job, that could be used to implement almost any task. As long as you call a method of Job class can implement a function, Job class changes very big, is a fat model, for the client if you only need a printing function, function also has nothing to do but other printing method and its coupling, ISP principle Suggestions on the client side and add an interface layer between Job class, for different functions have different interface, For example, the Print function is a Print interface, and then the large Job class is split into subclasses that inherit different interfaces, so there is a Print Job class, and so on.
Dependency inversion principle
(1) Dependency Inversion Principle (DIP) : Code should depend on abstractions, not implementations. (2) high-level modules should not depend on low-level modules, and both should depend on abstractions (3) Abstractions should not depend on details, and details should depend on abstractions (4) classes may depend on other classes to do their job. However, they should not depend on a specific concrete implementation of the class, but rather on its abstraction. This principle is really too important, social division of labor, standardization are the embodiment of this design principle. Obviously, this concept will greatly increase the flexibility of the system. If classes are only concerned with their use to support specific contracts rather than specific types of components, you can quickly and easily modify the functionality of these low-level services while minimizing the impact on the rest of the system.
Application of this principle:
For example, the switch on the wall should not rely on the light switch implementation, but should rely on an abstract switch standard interface, so that when we extend the program, our switch can also control other different lights, or even different appliances. That is, lights and other appliances inherit and implement our standard switching interfaces, and our switching manufacturers don’t need to worry about what equipment they control, just the standard switching standards. This is the dependency inversion principle. It is as if the browser does not depend on the web server behind it, but only on the HTTP protocol.
For more of Jerry’s original articles, please follow the public account “Wang Zixi “: