The open closed principle

define

The open closed principle states that software entities such as classes, modules, and functions should be open for extension and closed for modification. Emphasize the use of abstraction to build the framework, the implementation of the implementation of the details.

The advantages are improved software reusability and easy maintenance of the malleability. Is the most basic principle of object orientation.

Dependency inversion principle

define

High-level modules should not depend on low-level modules; both should depend on their abstractions. Abstractions should not depend on details: details should depend on abstractions. Program for interfaces, not implementations.

advantages

Reduced coupling improves stability, readability and maintainability of code. Reduce the risk of code changes.

The following code illustrates what the dependency inversion principle is

Suppose we wanted to fulfill a person’s need to learn, we could write it like this

/ * * *@authorHong-xing Yang *@version 1.0.0
 * @date2018/11/30 * /
public class Redstar {
    public void studyJava(a) {
        System.out.println("Redstar is learning Java");
    }

    public void studyFE(a) {
        System.out.println("Redstar on the learning front"); }}Copy the code

And then there’s a test class

/ * * *@authorHong-xing Yang *@version 1.0.0
 * @date2018/11/30 * /
public class RedstarTest {
    public static void main(String[] args) {
        Redstar redstar = newRedstar(); redstar.studyFE(); redstar.studyJava(); }}Copy the code

At this point, assuming we want to learn Python, we need to modify the Redstar class. This is implementation-oriented programming, because the entire Redstar class is an implementation class. This Redstar class is constantly being modified. It is also poor in extensibility. Our RedstarTest class is the application layer (high-level module) class that depends on the Redstar implementation class (low-level module). Because we don’t have abstractions. According to the dependency inversion principle, high-level modules should not be dependent on low-level modules. Every Redstar expansion is supplemented by RedstarTest.

We start with code with dependency inversion, first creating an interface. This interface has a learning method.

/ * * *@authorHong-xing Yang *@version 1.0.0
 * @date2018/11/30 * /
 
public interface ICourse {
    void studyCourse(a);
}

Copy the code

Let’s write some implementation classes that implement this interface


public class JavaCourse implements ICourse {

    @Override
    public void studyCourse(a) {
        System.out.println("Redstar is taking Java classes."); }}Copy the code
public class FECourse implements ICourse {
    @Override
    public void studyCourse(a) {
        System.out.println("Redstar is taking FE courses"); }}Copy the code

Note that the method type is an interface type, not a concrete class type. When this method is called, the interface type will transition down to execute the concrete method according to the type of the entity class.

/ * * *@authorHong-xing Yang *@version 1.0.0
 * @date2018/11/30 * /
public class Redstar {
    public void studyJava(ICourse iCourse) { iCourse.studyCourse(); }}Copy the code

Change the Test class to

/** * @author * @version 1.0.0 * @date 2018/11/30 */ public static void main(String[]) args) { Redstar redstar = new Redstar(); redstar.studyJava(new JavaCourse()); redstar.studyJava(new FECourse()); }}Copy the code

The output is

Redstar is taking Java courses and Redstar is taking FE coursesCopy the code

If there’s another big course you’d like to follow, you can add one by adding ICourse’s implementation class. The Redstar class doesn’t touch him. We have a high level class called RedstarTest to choose what courses we want to take. By the way, we inject a dependency to the ICourse interface using an interface method in the RedstarTest class. We can also inject dependencies using constructors.

/ * * *@authorHong-xing Yang *@version 1.0.0
 * @date2018/11/30 * /
public class Redstar {
    private ICourse iCourse;
    public Redstar(ICourse iCourse) {
        this.iCourse = iCourse;
    }

    public void studyJava(a) { iCourse.studyCourse(); }}Copy the code

This is what we should write in Redstar

/ * * *@authorHong-xing Yang *@version 1.0.0
 * @date2018/11/30 * /
public class RedstarTest {
    public static void main(String[] args) {
        JavaCourse javaCourse = new JavaCourse();
        FECourse feCourse = new FECourse();
        Redstar redstar = new Redstar(javaCourse);
        redstar.studyJava();
        redstar = newRedstar(feCourse); redstar.studyJava(); }}Copy the code

We have a constructor and we can also use a set, and that’s how we’re going to write our Redstar

/ * * *@authorHong-xing Yang *@version 1.0.0
 * @date2018/11/30 * /
public class Redstar {
    private ICourse iCourse;

    public void setiCourse(ICourse iCourse) {
        this.iCourse = iCourse;
    }

    public void studyJava(a) { iCourse.studyCourse(); }}Copy the code

The corresponding RedstarTest is going to look like this

/ * * *@authorHong-xing Yang *@version 1.0.0
 * @date2018/11/30 * /
public class RedstarTest {
    public static void main(String[] args) {
        JavaCourse javaCourse = new JavaCourse();
        FECourse feCourse = new FECourse();
        Redstar redstar = newRedstar(); redstar.setiCourse(feCourse); redstar.studyJava(); redstar.setiCourse(javaCourse); redstar.studyJava(); }}Copy the code

Okay, so that’s it for the dependency inversion principle, just to summarize the general principle is programming for interfaces, or programming for abstractions. The interface in the example above can also be replaced with an abstract class. Students can use abstract classes to simulate the above process.