Seven principles of software design

Today, let's talk about seven principles of software design:

1. Opening and closing principle:

According to Wikipedia, the principle of opening and closing is that objects (classes, modules, functions, etc.) in software should be open for extension, but closed for modification "[1], which means that an entity is allowed to change its behavior without changing its source code.

If you don't say much, let's code together

Simulation scenario:

For example, you buy a video course online to learn

package com.geely.design.principle.openclose;


public interface ICourse {
    Integer getId();
    String getName();
    Double getPrice();


}

package com.geely.design.principle.openclose;


public class JavaCourse implements ICourse{
    private Integer Id;
    private String name;
    private Double price;

    public JavaCourse(Integer id, String name, Double price) {
        this.Id = id;
        this.name = name;
        this.price = price;
    }

    public Integer getId() {
        return this.Id;
    }

    public String getName() {
        return this.name;
    }

    public Double getPrice() {
        return this.price;
    }

}

package com.geely.design.principle.openclose;


public class JavaDiscountCourse extends JavaCourse {

    public JavaDiscountCourse(Integer id, String name, Double price) {
        super(id, name, price);
    }

    public Double getDiscountPrice(){
        return super.getPrice()*0.8;
    }

    public Double getOriginPrice(){
        return super.getPrice ();
    }

}

package com.geely.design.principle.openclose;


public class Test {
    public static void main(String[] args) {
        ICourse iCourse = new JavaDiscountCourse(96, "Java From zero to enterprise e-commerce development", 348d);
        JavaDiscountCourse javaCourse = (JavaDiscountCourse) iCourse;
        System.out.println("curriculum ID:" + javaCourse.getId() + " Course title:" + javaCourse.getOriginPrice() + " Original price of course:" + javaCourse.getPrice() + " Course discount price:" + javaCourse.getDiscountPrice() + "element");


    }
}

Result:

Here we see that the price after discount has lost the accuracy, because this time the main content is not to deal with this problem, so I ignored it
Attached, class diagram:

2. Dependency Inversion Principle (class test our MVC, interface oriented programming)

The principle of dependency inversion is defined as follows:

  1. The upper module should not depend on the lower module, they should all depend on the abstraction.
  2. Abstraction should not depend on details. Details should depend on abstraction.

How do we understand the above definition? We need to bite the bullet and make breakthroughs.
Mapping to our actual software development, we will generally divide the software into modules, such as business layer, logic layer and data layer.
The business layer is the real operation of software, that is, what to do.
The logic layer is the implementation details provided by the software for the requirements of the business layer at this stage, that is, how to do it.
Data layer refers to the data model required by business layer and logic layer.

What is abstraction and detail?

Abstract, like its name, is a very abstract thing. Abstract is often relative to concrete, concrete can also be called details, of course, also known as concrete.
After understanding the above concepts, let's formally learn the principle of dependency inversion

Benefits of dependency inversion

In normal development, we will probably code like this.

public class Geely {
	 public void studyFECourse() {
        System.out.println("Geely I'm learning FE curriculum");
    }
     public void studyJAVACourse() {
        System.out.println("Geely I'm learning JAVA curriculum");
    }
}
public class Test {
	 public static void main(String[] args) {
        Geely geely = new Geely();
        geely.studyJavaCourse();
        geely.studyFECourse();
    }
}

It's OK to write in this way, but if there are many courses for Geely to learn, in this way, don't constantly change the Geely class to increase the complexity of the code, so this demand oriented programming is not recommended!

And the principle of dependence inversion is just suitable to solve this kind of situation.
Next, we try to use the dependency inversion principle to transform the code.
The first is the split of the upper module and the lower module.
Geely class obviously depends on ICourse class, so our improvement is as follows:
Class diagram first:

The code is as follows:
FECourse:

package com.geely.design.principle.dependenceinversion;


public class FECourse implements ICourse {
    @Override
    public void studyCourse() {
        System.out.println("Geely I'm learning FE curriculum");
    }

}

Geely:

package com.geely.design.principle.dependenceinversion;


public class Geely {

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

    public void studyImoocCourse(){
        iCourse.studyCourse();
    }
}

ICourse:

package com.geely.design.principle.dependenceinversion;


public interface ICourse {
    void studyCourse();
}

javaCourse:

package com.geely.design.principle.dependenceinversion;


public class JavaCourse implements ICourse {

    @Override
    public void studyCourse() {
        System.out.println("Geely I'm learning Java curriculum");
    }
}

pythonCourse:

package com.geely.design.principle.dependenceinversion;


public class PythonCourse implements ICourse {
    @Override
    public void studyCourse() {
        System.out.println("Geely I'm learning Python curriculum");
    }
}

Test:

    public static void main(String[] args) {
        Geely geely = new Geely();
        geely.setiCourse(new JavaCourse());
        geely.studyImoocCourse();

        geely.setiCourse(new FECourse());
        geely.studyImoocCourse();

    }

Single responsibility principle:

Definition: there should be no more than one reason for class changes. Generally speaking, a class is only responsible for one responsibility.


Direct code:

package com.geely.design.principle.singleresponsibility;


public class Method {
    private void updateUserInfo(String userName,String address){
        userName = "geely";
        address = "beijing";
    }

    private void updateUserInfo(String userName,String... properties){
        userName = "geely";
//        address = "beijing";
    }

    private void updateUsername(String userName){
        userName = "geely";
    }
    private void updateUserAddress(String address){
        address = "beijing";
    }

    private void updateUserInfo(String userName,String address,boolean bool){
        if(bool){
            //todo something1
        }else{
            //todo something2
        }


        userName = "geely";
        address = "beijing";
    }


}

In fact, in the actual development, the principle of single responsibility is very difficult to achieve

Interface isolation principle:


We have talked about the principle of single responsibility above, and here are the differences between the two:

Interface isolation principle and single responsibility principle:

From the functional point of view, the two principles of interface isolation and single responsibility have certain similarity. In fact, if we think about it carefully, there are differences.

(1) From the perspective of principle constraints, the principle of interface isolation pays more attention to the isolation of interface dependence and "high cohesion" of interface, while the principle of single responsibility pays more attention to the division of interface responsibilities.

(2) In terms of the degree of interface refinement, the single responsibility principle is more precise for the division of interfaces, while the interface isolation principle focuses on the isolation of interfaces with the same function. The minimum interface in interface isolation can sometimes be a common interface with multiple single responsibilities.

(3) The principle of single responsibility is more inclined to the constraints of business, and the principle of interface isolation is more inclined to the constraints of design architecture. It should be well understood that responsibilities are divided according to business functions, so the single principle is more business oriented, while interface isolation is more for "high cohesion" and architecture design.

The following is the code interface isolation principle

Simulation scenario:

Dogs and birds

Dimiter principle:




Obviously, the Boss class does not use Course, but is called directly by TeamLeader!

Finally, the code of this design pattern note is attached: https://gitee.com/professional/mai/java/design/patterns/tree/master/

45 original articles published, praised 5, visits 2007
Private letter follow

Tags: Java Programming Python

Posted on Tue, 03 Mar 2020 20:22:55 -0800 by dumdumsareyum