Solid principle "Turn"

Source: Internet
Author: User

S.O.L.I.D is the acronym for several important coding principles (programming Priciple) in object-oriented design (OOD) and object-oriented programming (OOP).

Principles of object-oriented design
SRP The single Responsibility Principle Single principle of responsibility
Ocp The Open Closed Principle Open Closure principle
Lsp The Liskov Substitution Principle The principle of the Richter replacement
Isp The Interface segregation Principle Interface Separation principle
DIP The Dependency inversion Principle Dependency Inversion principle

I. Single principle of responsibility (SRP)

Explaining this principle from an object-oriented perspective is: "There is never more than one factor that causes class changes." "or" a class that has and has only one responsibility. " This does not seem to be a good understanding, especially "there is never more than one factor that causes class changes." "This sentence is a little bit empty, let a person a little touch the mind."

We usually say "low coupling, cohesion". In my opinion, the "single duty" here is what we usually call "high cohesion", that is, a class can only accomplish the duties it should complete , cannot blame the responsibility, nor the more CU Xintian the blister, cannot become omnipotent God class. If your team implements loose "code collective ownership", in the process of coding a lot of people at the same time modify (maintain) the phenomenon of the same class, and the communication between members is not timely, active and unimpeded, then a long time, it is likely to appear "to assume too much responsibility" of the God class. At this point, refining the base class/interface and refining the refactoring will help us to eliminate or mitigate this design odor.

See an example:

This is a class structure diagram that violates the "single responsibility Principle".
Here, the rectangle class does the following two things:

    • Calculate the rectangular area;
    • Draw a rectangle on the interface (drawing device);

Also, there are two applications that use the rectangle class:

    • Computational Geometry Applications (Computational Geometry application) Use this class to calculate the area;
    • The graphical program (graphical application) uses this class to draw rectangles on the interface;

This violates the SRP (single responsibility principle). Because the rectangle class did two things, in one method it computed the area, in another way it returns a GUI that represents the rectangle. This brings up some interesting questions: we must include the GUI in the computational Geometry application. That is, when developing geometry applications, we must refer to the GUI library; the changes in the rectangle class in a graphical application can lead to changes in computational geometry applications, compilation and testing, and vice versa. So how can it be modified to conform to the principle of single responsibility?

The answer is: Split! Split responsibilities into two different classes, such as:

    • Rectangle: This class should only define the area () method;
    • Rectangleui: This class should inherit the rectangle class and define the draw () method.

Ii. Open Closure principle (OCP)

From an object-oriented design perspective, this principle can be understood as follows: "Software entities (classes, modules, functions, etc.) should be open to extensions and closed to modifications. "In layman's terms, it means that you (or a class of customers) should be able to extend the behavior of this class without modifying a class." In Ood, opening up to extensions means that the behavior of classes or modules can change, and we can change the modules in new, different ways, or meet the requirements in new applications, when demand changes.

In other words, the extension is open, and the modification is closed. We usually say that when adding functionality to a system, you should simply add new code and modify the original code as little as possible. It seems to me that this is the effect of following the principle of open closure. Once on the Internet to see such a word "where changes, packaging where." What this means is that we are going to encapsulate the changes in the system, that is, the changes are closed. At the same time, in order to cope with the expansion of system requirements (function), need abstraction!

Here the abstraction is the key. The state mode and strategy mode in design mode are the best embodiment of this principle.

To give an example:

A class structure diagram that violates the open closure principle.

Client-side code is directly oriented to the server-specific implementation of programming, lack of flexibility. This way, if the server is replaced by another server for some reason, the code of the client call server must be modified or replaced accordingly. This is actually the "implementation-oriented Programming" design odor!

So how do you modify it to get the right and flexible design?

The answer is: abstract! Abstracts an abstract base class for the server-side code (type) (defines a set of minimum interfaces for completing service responsibilities).

Here's the right design:

A class structure diagram that follows the open closure principle.

Basically, your abstraction is the core of your system, and if you're well-abstracted, it's likely that adding a new server type (extension) will only add a new type (inherited from Abstractserver). So the code should be as abstract as possible (abstractserver here), which will allow you to extend the abstraction and define a new implementation without modifying any client code. That is, "interface-oriented programming, not implementation-oriented programming"!

Iii. Liskov ' s replacement principle (LSP)

Liskov's substitution principle means: "Subtypes must be able to replace their base types." Or another way of saying, "where a base class reference is necessary, you must be able to use an object of the inheriting class without knowing it." "This principle is a prerequisite for ensuring that inheritance is used correctly." Usually we say, "Use a combination (delegate) rather than inherit" or " use inheritance only when you are sure that the relationship is Is-a ," because inheritance often results in "tight coupling" design.
In the basic object-oriented principle, "inheritance" is usually the relationship of "is a". If "Developer" is a "softwareprofessional", then the "Developer" class should inherit the "Softwareprofessional" class. The "is a" relationship is important in class design, but it is easy to get carried away, resulting in incorrect design using incorrect inheritance.

Look at one of the most classic examples:

Class structure diagram that follows the Liskov substitution principle.

Note: Here, the KingFisher (Kingfisher) class extends the bird base class and inherits the Fly () method, which is fine.

But there is a design problem with this class diagram:

Class structure diagram that violates the Liskov substitution principle.

Ostrich (ostrich) is a kind of bird, which undoubtedly, and inherit from the bird class, which conceptually says no problem. But can ostriches fly? No, then this design violates the LSP. Because it is not possible to use ostrich instead of bird. So, even in the real world seems to be no problem, in the class design, ostrich should not inherit from the bird class, here should be separated from the bird a non-flying class Noflybrid,ostrich should inherit the flightless birds noflybrid.

Why is LSP so important?

    • If there is no LSP, the class inheritance will be chaotic, and if the subclass is passed as a parameter to the method, the unknown behavior will occur;
    • If there is no LSP, unit tests that apply to the base class will not be successfully used for test subclasses;

Iv. Interface Separation principle (ISP)

This principle means that "clients should not be forced to rely on interfaces that they do not use." In other words, an interface or class should have as little behavior as possible (so what is called as little as possible?). is to be able to do its own job, it is also to ensure that the software system module granularity as little as possible to achieve a highly reusable purpose.

Interfaces contain too many methods to reduce their availability, such as a "fat interface" that contains a useless method, increases the coupling between classes. If a class wants to implement the interface, it needs to implement all the methods, although some may be completely useless for it, so doing so will introduce unnecessary complexity in the system and reduce the maintainability or robustness of the code.

The interface separation principle ensures that the implemented interfaces have their common responsibilities, which are clear, understandable, and reusable.

The following example fully illustrates that the "interface should contain only the necessary methods, not the other". If an interface contains too many methods, it should be split by detaching the interface.

This is a thick interface that violates the principle of interface separation.

Note that the Ibird interface contains the behavior of many birds, including the fly () behavior. Now if a bird class (such as ostrich) implements this interface, it needs to implement unnecessary fly () behavior (Ostrich does not fly). Therefore, this "fat interface" should be split into two different interfaces, Ibird and Iflyingbird, while Iflyingbird inherits from Ibird. As shown in the following:

In this case, reuse will become very flexible: If a bird does not fly (such as ostrich), it implements the Ibird interface. If a bird can fly (such as Kingfisher), then it realizes Iflyingbird.

Therefore, if we want to get a reusable solution, we should follow the interface separation principle and define the interface to contain only the necessary parts so that the interface can be reused wherever the interface function is needed.

V. Dependency inversion principle (DIP)

This principle means that high-level modules should not rely on the underlying modules, both of which should be dependent on their abstraction. In fact, "interface-oriented programming, do not face the implementation of programming," the intrinsic requirements.

Let's consider a real-world example to see the benefits of the dependency inversion principle for our software.

Your car is made up of a lot of parts such as engines, wheels, air conditioners and other components, right?

Note: Car here is a high-level module; It relies on abstract interfaces itoyotaengine and Ieighteeninchwheel.

and the concrete engine fifteenhundredccengine belongs to the bottom module, also relies on the abstract interface Itoyotaengine;

The specific wheel Eighteeninchwheelwithalloy also belongs to the underlying module and is dependent on the abstract interface Ieighteeninchwheel.

The car class above has two properties (engine and wheel list), both of which are abstract types (interfaces). The engine and wheel are pluggable because the car can accept any object that implements the declaration interface, and the car class does not need to make any changes.

There are many other object-oriented principles beyond the solid principle. Such as:

    1. "Combinatorial substitution Inheritance": this is to say that relative to inheritance, more inclined to use the combination;
    2. "The Law of the Piper": This means "the less you know about other classes, the better";
    3. "Common closure principle": This means that "related classes should be packaged together";
    4. "Stable abstract principle": This means that "the more stable the class, the more it should be composed of abstract classes";
Of course, these principles are not isolated, but closely linked, followed by one principle and followed by one or more principles, contrary to one of the principles is also likely to violate the other one or more principles. Design patterns are the result of the application of these principles in some specific scenarios. Therefore, the design pattern can be regarded as "framework" and the Ood principle as "norm".      In the process of learning the design pattern, we should constantly reflect on, this design pattern embodies the object-oriented design principles of which or some of the principles. Especially in the process of reconstructing the mode of implementation, or reconstructing the trend pattern, we should consider the difference between the code and the refactoring before and after the reconstruction, and understand its improvement.      I'm studying refactoring and patterns, so I'll follow an example to record my own learning experience. Note: The film is from "How to explain to wife OOD" link: http://www.cnblogs.com/niyw/archive/2011/01/25/1940603.html

Solid principle "Turn"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.