Vitaly's WebLog
Writing on software development and all related

The Open-Closed Principle and a SWITCH Statement

November 28, 2007
The Open-Closed Principle

The Open-Closed Principle (OCP) is one of the fundamental rules of object-oriented design that a software developer should always keep in mind. This principle has been formulated by Bertrand Meyer in 1988, and later, in 1996, has been analyzed and amplified by Robert C. Martin in his considerable writing for The C++ Report.

Here is what this principle states:

Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. The Open-Closed Principle, Robert C. Martin

This statement is not evident for most of us without additional comments:

Software entity is open for extension, when its behavior can be extended somehow. For example, a class can be extended by creating another class inherited from it. Or you can extend it by changing its source code by adding new methods or modifying existing (but this is not good as the principle says, see below).

Software entity is closed for modification, when its source code prohibited modifying. No one dares to change source code once it is written and tested; the only case allowed is to fix error.

So, the principle can be paraphrased in the following way:

Software entities (classes, modules, functions, etc.) should be extended by writing new code (using inheritance and polymorphism), instead of modifying existing.

Ok, maybe the above statement is not 100% accurate. But it should be easier to use it when describing what is the OCP to a novice developer and you even can try to describe it to your mom.

The OCP helps us to design software with maintainable and reusable code.

Conformance to this principle is what yields the greatest benefits claimed for object oriented technology; i.e. reusability and maintainability. Yet conformance to this principle is not achieved simply by using an object oriented programming language. Rather, it requires a dedication on the part of the designer to apply abstraction to those parts of the program that the designer feels are going to be subject to change. Robert C. Martin

When reviewing code, I like to find the OCP violations by looking at switch statements. It seems to be the easiest way to violate the OCP is in switch statements, as well as to find these violations.

Look at the following code snippet:

protected override ContentViewBase CreateContentView(UIEntityType uiEntityType)
{
    ContentViewBase contentView = null;
    switch (uiEntityType)
    {
        case UIEntityType.Account:
            contentView = CreateAccountContentView();
            break;
         case UIEntityType.Invoice:
            contentView = CreateInvoiceContentView();
            break;
    }
    return contentView;
}

What if there will be one more UIEntityType besides Account and Invoice? Right, you will add one more case statement. Perhaps, the code snippet is not so bad, if you know for sure that there will not be such kind of changes, but you should think twice when writing such code.

Another example:

SEC Speller::SpellerCheck(SPLID splid, SCCC iScc, LPSIB lpSib, LPSRB lpSrb)
{
    SpellSession *session = (SpellSession*) splid;
    switch(iScc)
    {
    case sccVerifyWord:
    case sccVerifyBuffer:
        return VerifyBuffer(*session, lpSib, lpSrb);
        break;
    case sccSuggest:
        return Suggest(*session, lpSib, lpSrb);
        break;
    case sccSuggestMore:
        return SuggestMore(*session, lpSib, lpSrb);
        break;
    default:
        MessageBox(NULL, L"Command is not supported!", NULL, MB_OK);
        break;
    }
    return secNOERRORS;
}

From this code we see that SCCC is, most likely, external component that sends commands to Speller class. Code above is not closed to changes that may occur in external component. That is, adding one more type of command will entail necessity of changes in Speller class that has been already tested. For the other hand, if SCCC is much less changeable than the Speller, then the code above may be ok.

So, you should always have Open Closed Principle in mind when writing code. Good developer predicts the changes that possibly may occur in software and closes it against them. When you have a set of several similar objects, actions, behaviors etc… that are handled together, you have quite high certainty that there will be one more of them in that set in the future. I'm not sure why, but that happens. And of course, there may be lot of other changes that may occur and that you should try to foresee.

Now open you code and try to explore several of your last switch statements… Wink


Related posts

Comments

Add comment