Six principles of object orientation

Six principles of object orientation

This is the first article in the beginning of the Design Patterns series. It is also a summary of my learning design pattern process. This article mainly talks about the six principles we should follow in object-oriented design. Only by mastering these principles can we better understand design patterns.

We will introduce the following 6 contents next.

  1. Single Responsibility Principle - SRP
  2. Open-Closed Principle - OCP
  3. Li-style substitution principle - LSP
  4. Dependency Inversion Principle - DIP
  5. Interface Isolation Principle - ISP
  6. Principle of Demeter - LOD

The principle of single responsibility

The definition of the single responsibility principle is that for a class, there should be only one reason for it to change. That is, a class should only be responsible for one thing. If a class is responsible for two different things, method M1 and method M2, when the M1 method changes, we need to modify the M1 method of this class, but at this time, the M2 method may not work. This is not what we expected, but it is very likely to happen due to this design. So at this time, we need to separate the M1 method and the M2 method into two classes. Let each class concentrate only on its own methods.

The benefits of the Single Responsibility Principle are as follows:

  1. The complexity of the class can be reduced, and a class is only responsible for one responsibility, so the logic is much simpler
  2. Improve the readability of the class, and the maintainability of the system, because there are no other strange ways to interfere with our understanding of the meaning of the class
  3. When a change occurs, the impact of the change can be minimized, because only changes are made in this class.

The principle of opening and closing

The Open-Closed Principle, like the Single Responsibility Principle, is a very basic and generally common sense principle. The Open-Closed Principle defines that objects in software (classes, modules, functions, etc.) should be open for extension, but closed for modification.

When the requirements change, we need to modify the code. At this time, we should try to extend the original code instead of modifying the original code, because this may cause more problems.

This principle, like the Single Responsibility Principle, is a principle that everyone believes in but does not specify how to do it.

The Open-Closed Principle We can ensure it in one way, we use abstractions to build frameworks and implementations to extend details. In this way, when a modification occurs, we directly use abstraction to derive a concrete class to implement the modification.

3. The Liskov Substitution Principle

Liskov Substitution Principle: All references to a base class must be able to transparently use objects of its subclasses.

Liskov's substitution principle is commonly said: subclasses can extend the functions of the parent class, but cannot change the original functions of the parent class. It contains the following meanings:

  1. Subclasses can implement abstract methods of superclass, but cannot override non-abstract methods of superclass.
  2. Subclasses can add their own unique methods.
  3. When a method of a subclass overrides a method of the superclass, the formal parameters of the method are looser than the input parameters of the superclass method.
  4. When the method of the subclass implements the abstract method of the superclass, the return value of the method is stricter than that of the superclass.

The Liskov Substitution Principle is required because inheritance has many shortcomings. Although it is a method of reusing code, inheritance violates encapsulation to a certain extent. The properties and methods of the parent class are transparent to the child class, and the child class can modify the members of the parent class at will. This also causes other subclasses to fail to work properly if the requirements change and the subclass overwrites some methods of the parent class. So the Liskov Substitution Rule was proposed.

Ensuring that programs follow the Liskov Substitution Principle can require our programs to build abstractions, build specifications through abstractions, and then extend details with implementations. This sounds familiar, yes, Liskov Substitution Principles and Open-Closed Principles are often interdependent.

4. Dependency Inversion Principle

Dependency Inversion Principle: A special way of decoupling such that high-level modules should not depend on low-level modules for the purpose of implementation details, and dependent modules are reversed.

This is also a difficult definition, he can simply say

  1. High-level modules should not depend on low-level modules, both should depend on their abstractions
  2. Abstraction should not depend on details
  3. Details should rely on abstractions

Abstraction in Java refers to an interface or an abstract class, neither of which can be instantiated. The details are the implementation class, that is, the class that implements the interface or inherits the abstract class. It can be instantiated. The high-level module refers to the calling end, and the bottom-level module is the specific implementation class. In Java, the dependency inversion principle means that the dependencies between modules occur through abstraction, and there is no direct dependency relationship between implementation classes, and the dependency relationship is realized through interfaces. This is commonly known as interface-oriented programming.

We have an example below to illustrate this problem. This example is of a worker using a hammer to fix something. Our code is as follows:

public class Hammer {
    public String function(){
        return "用锤子修理东西";
    }
}

public class Worker {
    public void fix(Hammer hammer){
        System.out.println("工人" + hammer.function());
    }


    public static void main(String[] args) {
        new Worker().fix(new Hammer());
    }
}

This is a very simple example, but if we want to add a new function, workers use screwdrivers to repair things, in this class, we find it difficult to do. Because our Worker class depends on a concrete implementation class Hammer. So we use the idea of ​​interface-oriented programming and change it to the following code:

public interface Tools {
    public String function();
}

Then our Worker relies on other detailed classes through this interface. code show as below:

public class Worker {
    public void fix(Tools tool){
        System.out.println("工人" + tool.function());
    }


    public static void main(String[] args) {
        new Worker().fix(new Hammer());
        new Worker().fix(new Screwdriver());

    }
}

Our Hammer class and Screwdriver class implement this interface

public class Hammer implements Tools {
    public String function() {
        return "用锤子修理东西";
    }
}

public class Screwdriver implements Tools {
    @Override
    public String function() {
        return "用螺丝刀修理东西";
    }
}

In this way, through interface-oriented programming, our code has high scalability, which reduces the coupling between codes and improves the stability of the system.

Five, interface isolation principle

Interface Segregation Principle: A client should not depend on interfaces he does not need. In other words, the dependencies between classes should be established on the smallest interface.

We illustrate with an example. We know that a concrete class implements an interface in Java, so it must implement all the methods in the interface. If we have a class A and class B depend on through interface I, class B is the implementation of class A depend on, this interface I has 5 methods. But class A and class B only depend on methods 1, 2, and 3, and then class C and class D depend on interface I. Class D is the implementation of class C's dependency, but they depend on methods 1, 4, and 5. Then, when implementing the interface, class B must implement method 4 and method 5 that he does not need, and class D must implement method 2 and method 3 that he does not need. This is simply a disaster design.

Therefore, we need to split the interface, which is to divide the interface into the smallest interface that satisfies the dependencies. Class B and class D do not need to implement interface methods that have nothing to do with them. For example, in this example, we can split the interface into 3, the first is the interface with only method 1, the second interface contains methods 2 and 3, and the third interface contains methods 4 and 5.

In this way, our design satisfies the interface isolation principle.

The above design ideas can be composed of SOLID with the first letter of English, and the program that satisfies the 5 principles is also called satisfying the SOLID criteria.

The principle of Demeter

Demeter's Principle: Also known as the principle of least knowledge, it states that an object should have minimal knowledge about other objects.

Because the closer the relationship between classes, the greater the degree of coupling, when one class changes, the greater the impact on another class, so this is also the general principle of software programming we advocate: low coupling, high Cohesion.

The Law of Demeter has an even simpler definition: Only communicate with immediate friends.

First, let's explain what a direct friend is: each object will have a coupling relationship with other objects. As long as there is a coupling relationship between two objects, we say that the two objects are friends. There are many ways of coupling, such as dependency, association, composition, aggregation, etc. Among them, we call the classes that appear in member variables, method parameters, and method return values ​​as direct friends, while classes appearing in local variables are not direct friends. That is to say, unfamiliar classes are best not to appear inside the class in the form of local variables.

Here we can use a real life example to explain. For example, if we need a CD, we may go to a video store and ask the boss if he has the CD we need. Here we don't need to care where and how the boss got the CD, we only communicate with the boss (direct friends), as for what conditions the boss got the CD from his friends, we don't care, we don't talk to the boss. The boss's friend (stranger) communicates, this is an application of Dimit. To put it bluntly, it is an intermediary method. We use the boss as an intermediary to get in touch with the person who actually provides the CD.


Record a little bit every day. Content may not be important, but habits are!

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325383406&siteId=291194637