Opening and closing principles of 23 design modes

Keywords: Java Design Pattern mvc

Open Closed Principle

Basic introduction:

The opening and closing principle is the most basic and important design principle in programming

A software entity such as class, module and function should be open to extension (for the provider) and closed to modification (for the user). Build the framework with abstraction and extend the details with implementation.

When the requirements of software change, try to realize the change by expanding the behavior of software entities, rather than by modifying the existing code

Other principles are followed in programming, and the purpose of using design patterns is to follow the opening and closing principles
Code example
There is such a drawing class

/**
 * @create: 2021/9/26
 * @author: Tony Stark
 */
public class Ocp {
    public static void main(String[] args) {
        GraphicEditor graphicEditor = new GraphicEditor();
        graphicEditor.drawCircle(new Circle());
        graphicEditor.drawRectangle(new Rectangle());
    }
}

/**
 * This is a class for drawing
 */
class GraphicEditor {
    /**
     * Accept the Shape object and draw different shapes according to the type
     */
    public void drawShape(Shape s) {
        if (s.m_type == 1) {
            drawRectangle(s);
        } else if (s.m_type == 2) {
            drawShape(s);
        }
    }

    public void drawRectangle(Shape r) {
        System.out.println("rectangle");
    }

    public void drawCircle(Shape r) {
        System.out.println("circular");
    }
}

/**
 * Base class
 */
class Shape {
    int m_type;
}
class Rectangle extends Shape {
    Rectangle() {
        super.m_type = 1;
    }
}
class Circle extends Shape {
    Circle() {
        super.m_type = 2;
    }
}

Advantages and disadvantages of mode 1:

1. The advantages are easy to understand and easy to operate.

2. The disadvantage is that it violates the ocp principle of design pattern, that is, it is open to extension and closed to modification. That is, when we add new functions to the class. Try not to modify the code, or modify the code as little as possible

3. For example, if we want to add a new square type, we need to modify it. There are many modifications

For example, we add a square class

class Square extends Shape{
    Square(){
        super.m_type=3;
    }
}

Add corresponding method

/**
 * This is a class for drawing
 */
class GraphicEditor {
    /**
     * Accept the Shape object and draw different shapes according to the type
     */
    public void drawShape(Shape s) {
        if (s.m_type == 1) {
            drawRectangle(s);
        } else if (s.m_type == 2) {
            drawShape(s);
        }else if (s.m_type==3){
            drawShape(s);
        }
    }

    public void drawRectangle(Shape r) {
        System.out.println("rectangle");
    }

    public void drawCircle(Shape r) {
        System.out.println("circular");
    }
    public void drawSquare(Shape r) {
        System.out.println("square");
    }
}

call

public class Ocp {
    public static void main(String[] args) {
        GraphicEditor graphicEditor = new GraphicEditor();
        graphicEditor.drawCircle(new Circle());
        graphicEditor.drawRectangle(new Rectangle());
        graphicEditor.drawSquare(new Square());
    }
}

It can be seen that we have to change very cumbersome and need to modify the existing code, which violates the opening and closing principle

Improve according to the opening and closing principle

Make the Shape class into an abstract class and provide an abstract draw method for the subclass to implement. In this way, when we have a new graphics type, we only need to let the new graphics class inherit Shapa and implement the draw method. The user's code does not need to be modified to meet the opening and closing principle.

/**
 * @create: 2021/9/26
 * @author: Tony Stark
 */
public class Ocp {
    public static void main(String[] args) {
        GraphicEditor graphicEditor = new GraphicEditor();
        graphicEditor.drawShape(new Circle());
        graphicEditor.drawShape(new Rectangle());
        graphicEditor.drawShape(new Square());
    }
}

class GraphicEditor{
    public void drawShape(Shape s){
        s.draw(s);
    }
}

/**
 * Base class
 */
abstract class Shape {
    int m_type;

    /**
     * Method of drawing graphics
     * @param s
     */
    public abstract void draw(Shape s);
}

class Rectangle extends Shape {
    Rectangle() {
        super.m_type = 1;
    }

    @Override
    public void draw(Shape s) {
        System.out.println("draw rectangle");
    }
}

class Circle extends Shape {
    Circle() {
        super.m_type = 2;
    }

    @Override
    public void draw(Shape s) {
        System.out.println("Draw circle");
    }
}

class Square extends Shape {
    Square(){
        super.m_type=3;
    }

    @Override
    public void draw(Shape s) {
        System.out.println("Draw triangle");
    }
}

At this time, we only need to inherit the Shape base class when we extend the new function

Posted by markthien on Thu, 30 Sep 2021 18:39:24 -0700