SOLID Principles : Part 2 of 5, Open Closed Principle.

Hey why did the Java developer need glasses??? Because he couldn’t C#!!!!

I hope you found that as funny, as you find this next topic interesting, the open closed principle. The open closed principle states that a class should be closed for modification, but open for extension. Why don’t we take a look at an example.

What if your requirements were to build a version of Cribbage? One of the key parts of our program is how a hand gets scored at the end of each turn. You get two points for using any amount of cards that make 15, two points for pairs, points for runs of 3 or more(5, 6, 7 for instance). Your class might look similar to this.

We are scoring runs, pairs, and ways to make fifteen, and then adding those scores together to return a final score. Aggregate is exactly like the reduce method in other languages.

You are just putting the finishing touches on this part of the project when your client calls.

Demanding Client : Hey Bob it’s me, that guy that is paying you all this money to build a command line cribbage game. I actually don’t want just one game a want this thing to be able to run different types of card games.

Now we are in a little bit of a pickle! Our Hand Evaluator class is not open for extension! We can not extend the functionality of the the HandEvaluator class the way it is built so therefore we are breaking the Open Closed Principle.

One common solution when we find ourselves breaking OCP is to use an interface. Our interface will still be called Hand Evaluator. This interface Hand Evaluator won’t have any details about how a hand is evaluated, very simply it will have the function name, and the type we expect that function to return.

public class HandEvaluator
{
int Score(string[] cards);
}

Now any class that uses this interface must have a method called Score. Now we have the ability to score any hand, from any card game.

public class CribbageHand : HandEvaluator
{
    public static int Score (string[] cards) 
{
List<int> scores = new List<int>();
scores.Add(Runs(cards));
scores.Add(Pairs(cards));
scores.Add(MakeFifteen(cards));
return scores.Aggregate(0, (acc, score) => acc + score);
}
}

Look at that, now we are following OCP. Our Hand Evaluator interface is open for extension, by using this interface we can now implement how a hand is scored for different card games.

Tune in next time where we’ll be discussing the L in SOLID Principles, the Liskov Substitution Principle.