The Open-Closed Principle: The heart of object oriented design

I have a question for you guys and girls.

This morning, I was reading through the Spring documentation about the Web MVC framework.
In a side-note, “Open for extension…”, SpringSource referred to a paper about the design principle “Open for extension, closed for modification”.

A key design principle in Spring Web MVC and in Spring in general is the “Open for extension, closed for modification” principle.

Some methods in the core classes of Spring Web MVC are marked final. As a developer you cannot override these methods to supply your own behavior. This has not been done arbitrarily, but specifically with this principle in mind.

I found this comment somewhat contradictory to the Open-Closed Principle.

I read the paper of (Uncle) Bob Martin, which can be found at the link The Open-Closed Principle, and wanted to share my thoughts with you.

The paper gives a very good and understandable explanation about this OOD (Object Oriented Design) principle.
It’s all about abstraction, encapsulation and design for change, which are principles that lie at the heart of OOD.
You have to write your code in such a way that, if you need to change the behavior of your application, you just extend instead of modify your existing code base. In the most ideal circumstance, you should not touch any lines of code that you have written in the past.

A procedural design

Bob Martin uses shapes as an example. You could write code like the following listing to create a Client-Server application that draws shapes.

public class Shape {
    ShapeType type;
}
public class Circle extends Shape {
    public Circle() {
        this.type = ShapeType.CIRCLE;
    }

    double radius;

    Point center;
}
public class Server {
    void drawSquare(Square square) {
        System.out.println("I'm drawing a square");
    }

    void drawCircle(Circle circle) {
        System.out.println("I'm drawing a circle");
    }

    void drawAllShapes(List<Shape> shapes) {
        for (Shape shape : shapes) {
            switch (shape.type) {
            case SQUARE:
                drawSquare((Square) shape);
                break;
            case CIRCLE:
                drawCircle((Circle) shape);
                break;
            }
        }
    }
}

You can see immediately that if you need a new kind of shape, you need to create a new class for this shape (which is good), but you also need to modify the entire Server class. You have to add another draw method, and you need to change the switch in the drawAllShapes method.
So, a lot of changes in your existing code are necessary just to use a new kind of shape.

An Object Oriented Design

To be able to add new shapes without having to change your existing code base, you can do the following:

public abstract class Shape {
    public abstract void draw();
}
public class Circle extends Shape {
    private double radius;

    private Point center;

    // Getters and setters

    @Override
    public void draw() {
        System.out.println("I'm drawing a circle");
    }
}
public class Server {
    public void drawAllShapes(List<Shape> shapes) {
        for (Shape shape : shapes) {
            shape.draw();
        }
    }
}

As you can see, your code becomes much more concise, readable and when you want to add a new kind of shape, you just extend the Shape class and implement the draw method in that new class. “Open for extension, …”.
Also, you don’t need a ShapeType attribute anymore, because the new shape class IS the type!

This principle goes a lot further, but you can read the rest in Bob Martin’s excellent paper.

My question about this matter

What does SpringSource mean with “Some methods in the core classes of Spring Web MVC are marked final. […] This has not been done arbitrarily, but specifically with this principle in mind.

If the Open-Closed Principle stands for “Open for extension, …” what do final methods have to do with this principle?
Final methods cannot be overridden in subclasses. Thus that behavior cannot be extended. It is closed for modification but I thought that had to do with not touching the existing code base, while being able to change it’s behavior by extending classes and overriding methods.

Can you guys and girls elaborate on this with me?
Feel free to post your comments to this blog post.

As usual, you can find the source code at the following link: shapes-demo.
You won’t need Maven to build this demo. Just extract it in your Eclipse workspace, and import the existing project. You might need to change the classpath to add your own JRE System Library.

Advertisements

About Steve Schols

I am Steve Schols, a senior Java consultant working for several clients in Belgium. I mainly blog about the Java language and relevant frameworks and technologies. All statements made here are solely my own and do not represent the opinion of my employer, colleagues or my clients.
This entry was posted in Java, Object Oriented Design and tagged , , , , . Bookmark the permalink.

3 Responses to The Open-Closed Principle: The heart of object oriented design

  1. sanderdevos says:

    You cannot override framework specific methods. Spring offers support plans, this is nearly impossible if every developer is able to override core capabilities of the framework.

    The open-closed principle is still present: you don’t need to change the internals of the framework to tweak the behaviour. You make and inject your own interface implementations, hook into listeners and events, extend classes and more.

    Point is: only internal final methods cannot be overridden, you can still extend the class and make your own version and reference another implementation.

    HTH

    Sander

  2. I initially felt moving the draw method in Circle and Square will violate the Single Responsibility Principle. But then a I remembered a thing I read some where and that said ‘identify the change’, only we need to isolate the draw from Circle if it has to change, i.e. if we have different ways to draw a Circle. [May be there is a draw on paper by printing it, or draw on the screen, or draw using different versions of graphics lib]… so +1 for the simple and clear example…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s