Skip to main content
1 of 2

There is another way of thinking about this.

Consider the code that is being refactored:

 // Original code
 class GraphicEditor {

    public void drawShape(Shape s) {
        if (s.m_type==1)
            drawRectangle(s);
        else if (s.m_type==2)
            drawCircle(s);
    }
    public void drawCircle(Circle r) {....}
    public void drawRectangle(Rectangle r) {....}
 }

Seems like that original code already "involves interaction with a GUI". The classes Shape, Circle, and Rectangle are already part of the original code. So it seems to me that these classes also "interact with the GUI".

If we change the names into GraphicalShape, GraphicalCircle, and GraphicalRectangle, the confusion might be erased.


Another way to phrase it:

What the refactoring did (to conform to the OCP) is to move the code (which "involves interaction with the GUI") from drawCircle(Circle c)...

public void drawCircle(Circle c) {
    // draw the circle, c
    // might have "involved interaction with a GUI"
}

...into the draw() method inside the Circle class

 class GraphicalCircle extends GraphicalShape {
    public void draw() {
        // draw the circle, this
        // might "involve interaction with a GUI"
    }
 } 

And you should remember that there is a goal for doing that. (You do not do it just for the sake of conforming to the SOLID principles.) The goal is so that you will not need to modify the GraphicalEditor class if you need to add another Shape. Your GraphicalEditor class is closed for modification (in relation to drawing new shapes) but open to extension (of drawing new shapes).

(If you knew in the first place that you will be drawing only circles and rectangles, you will not need to do the refactoring to conform to OCP.)

By obeying the OCP you changed the responsibility of the GraphicalEditor. Previously it has two responsibilities: (1) orchestrate the drawing of shapes (2) draw the shapes.

Now it has only one responsibility: orchestrate the drawing of shapes. You removed the responsibility of drawing the circle from the GraphicalEditor into the GraphicalCircle class. And the responsibility of drawing the rectangle into the GraphicalRectangle class.


One more way to phrase it:

The purpose of the Circle class is to contain the responsibilities of a GUI for a circle. So it obeys the SRP even when it contains code that interacts with GUI.

The purpose of the Circle.draw() class is to contain the responsibility for drawing GUI for a circle. So it obeys the SRP even when it contains code that interacts with GUI.