Saturday, February 13, 2021

Strategy? My two cents on Design Patterns

This may seem a bit out of the blue. But I've been reading a bit on Design Patterns lately. 🤓 Even though there are plenty of materials out there on the topic, I still thought it was worth making a note out of. So here goes nothing.

For someone who have formally studied Computer Science, Design Patterns most probably must have been one of the first and foremost things to learn. For people like us, who came in to already vastly evolved computer science world, this might seem like just another theory, but thinking back to a time when these 'theories' didn't exist, it must have been really challenging developing rapidly growing and robust systems. 

Design Patterns, just like most of other theories in computer science, came to be from within the community itself. Developers, who encountered problems and found solutions in the systems they are developing, could see same thing happening all over again to fellow developers. They identified these common patterns that can be universally applied to similar systems and called them Design Patterns.

When it comes to software systems, we often have to think about objects, classes and relationships. We can apply design patterns to all of these aspects. We have patterns that takes object instantiation in to consideration, patterns that focus on class relationships and patterns that can be applied to object behaviors. Let's look at some famous design patterns divided into these categories.




One of the first design patterns I came across early in my carrier was the Strategy Pattern. Like most of us, I honestly did not expect to see the theories I studied being applied on live projects, and I was pleasantly surprised.😇 So I'm gonna make this post about this particular pattern.

Let me put forth the definition of the Strategy Pattern I studied way back in the good old university days here first. 👀

"The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it"

😕

I have no idea why these definitions have to be so hard to grasp, but this particular one is not so bad in my opinion. This simply implies that we can design a class, which uses some algorithm to do something, such that we can switch that algorithm without affecting the class itself. To give you an example, let's say we have a List class that has a 'sort' method. We should be able to switch the algorithm used in the sort method to any algorithm we want, be it the quick sort, the bubble sort or any other sort, without changing the List class. Sounds powerful, isn't it? Let's look at some UML Diagrams then.



Above diagram demonstrates how we can apply strategy pattern to the example I just gave. We can say that we have multiple sort 'strategies' or 'behaviors' or as per the definition, 'related algorithms' and we need to use them inter changeably in out list classes or 'clients' without changing any of them.

The List class above is the super class to all the list implementations which is denoted by the inheritance arrow. We call that relationship an 'is-a' relationship. LinkedList is-a List, ArrayList is-a List, so forth.  Where as the relationship between the List and the ISortStrategy is a 'has-a' relationship. In formal words, a Composition relationship. This is the relationship that makes it possible for us to switch the sorting algorithms as we see fit.

Let's say we want our ArrayList to have BubbleSort as it's sort method. Here's How we do this.

List arrayList = new ArrayList()
ISortStrategy bubbleSort = new BubbleSort()
arrayList.setSortStrategy(bubbleSort)
arrayList.performSort()  //will sort using  bubble sort


Now if we wanted to switch the algorithm to CustomSort, that's very easy to do.

ISortStrategy customSort = new CustomSort()
arrayList.setSortStrategy(customSort)
arrayList.performSort()  //will sort using  custom sort

See, we didn't have to do a single change to any of our List classes. Plus it's easier to introduce new sort algorithms to our system. This is how powerful the Strategy Pattern is. ðŸ’¥

This went longer than I expected. So I'm gonna stop my rambling now. Well, in a gist, Strategy Pattern encourages Composition over Inheritance because, with inheritance, the systems tend to get too complicated and unmaintainable with rapidly growing systems. 

Finally I want to introduce this amazing book I'm reading on Design Patterns, "Head First Design Patterns". I've never been more enthusiastic about a theory book until I got my hands on this one. Really cool writing style, as the title says, "A Brain Friendly Guide". KUDOS to the Authors!

See you in another post!


Link to the Book