Table of contents
What to expect from this series?
Whether you are a newbie or an experienced programmer, you might have come across the term – “Software Design Patterns” many times in your career and would be actively using them knowingly or unknowingly in your code.
What are design patterns? How does it help a developer? How do we implement them? Well, this series here – Design patterns simplified aims at answering these questions along with explaining various design patterns with code samples and practical scenarios on when to use which pattern.
I will keep this series as simple as possible for the beginners and concise enough for the ace programmers out there. I am not venturing to explain the basic object-oriented concepts further. However, knowing them would help you understand this series much better.
All the code samples throughout this series will be added (As each new part is added to the series) here -https://github.com/artofcoding-dev/design-patterns. They are written in C#, but I hope programmers in any other language would be able to understand them and use the concepts.
What are Software Design Patterns?
Ever got stuck thinking about how to solve a problem effectively while writing code? If your answer is “Yes”, then please realise that you are not the first person who faced the same kind of problem. Those who have faced them earlier, have already solved it for you. All you need to do is reuse them instead of trying to reinvent the wheel.
Design patterns could be considered as a general purpose abstraction of a problem. In simple words, they are general, reusable, tested solutions for specific recurring problems a developer faces in their day to day programming. When I mention solution, it is not a code snippet which is ready for reuse or copy-paste. Instead, it provides a framework or template for achieving your requirements in the best possible way. Similar to how a recipe helps you cook a dish, it helps you with the measures, approaches, and ingredients to come up with a better software.
How does it help a developer?
Here are some of the advantages developers could have by using design patterns.
Improves code quality
Understanding design patterns will provide you with the required insights that would help you design a robust, flexible, scalable, loosely coupled, modular and reusable software.
Along with the obvious advantage of having a proven solution, it is also helpful in maintaining your code relatively clean, and resourceful in improving the quality of your documentation.
But also keep in mind that a good design is not the only ingredient of a good software. However good the design is, the quality of a software greatly depends on how the design is implemented as well. Having a good design will equip you in solving countless issues that may come up during the course of development, and a poor implementation can spoil the soup.
Since the patterns are tried, tested and improved by developers over time, it reduces the element of risk and effort required in testing.
Ease of communication and documentation
Design patterns are language neutral and could be applied to any object-oriented programming language. This makes things easy for developers to communicate efficiently, ensuring everyone is on the same page and helps them to visualise the design in their mind.
Impact on productivity
Using design patterns reduces the time spent on maintaining the code and provides better consistency. Even though they have a positive impact on the development timeline, don't expect a drastic reduction on your initial development timelines. Figuring out the optimum design usually consumes time as it is required to account for the time needed to analyse the requirements, finalising the right tools and training the team if needed. But it will be beneficial in the long run, when you need to introduce changes to it or add to it later.
How to find the right design patterns?
There are plenty of design patterns available, and choosing the appropriate one would be a tough call to make initially. Remember, the key here is your requirements. You are trying to solve your problems with design patterns, and not the other way around. It should specifically address your requirements and, at the same time, maintain a general openness to account for future problems. It is quite natural for us to stick to the methods familiar to us for solving problems. Every so often, it may not be the optimal solution. What experienced programmers and designers do is not to prematurely solve the problems without giving it enough thought. Furthermore, it takes a lot of patience and practice, mastering the art of designing good software.
Example: If the problem is to cross a river. The following could be considered the solutions:
Swimming across the river
Using a boat
Constructing a bridge across a river
All these solve the same problem. Swimming would solve it for one person, a boat would solve it for a few people at the same time, and a bridge would solve the issue for everyone. Considering the risks involved and other factors, a bridge would seem to be the ideal solution. But it would take longer to build and would cost more to implement. This would restrict people from travelling until the construction is completed. So here, the optimum solution would not be just to build the bridge. Instead, it will be a hybrid solution that involves constructing a bridge and using a boat until the bridge is constructed.
Blindly following a pattern would not be the best thing under certain situations. As developers, our primary focus should always be on the “WHAT” part instead of the “HOW” part of the problem. It enables us to solve the issues efficiently. In the example above, the focus should be on facilitating the travel rather than building the bridge (i.e. Implementing the pattern) which will lead us to the hybrid approach.
Another word of caution for the developers would be to avoid the overuse of design patterns. It is always good to remember YAGNI principle(https://artofcoding.dev/14-principles-every-developer-should-know#heading-7-you-arent-gonna-need-it-yagni) and find the right balance.
Types/Categories of Design Patterns
Design patterns could be broadly classified under 3 categories based on their purpose:
These patterns focus more on the effective communication and interaction between various components and objects and the assignment of responsibilities.
Example: Consider a restaurant where there is a chef, a waiter, and clients. The responsibility of the chef is to cook, the waiter takes and executes the orders and clients places orders and makes payment. The client and the chef need not see or communicate directly. But there in an indirect, effective communication happening through the waiter.
Few of the prominent behavioral patterns are:
Chain of responsibility pattern
Structural design patterns focus more on the template for defining the structure and components of a class. It helps the programmers to organise the classes and objects and helps in ensuring efficiency and flexibility of the component/software.
Some popular structural patterns are:
Creational design patterns focus more on object creation and initialisation. It empowers the developer in deciding which object is to be created in a specified scenario.
Example: A developer wants to log errors in the application, and decides to use a single logger instance.
Well known creational design patterns are:
Abstract Factory Patterns
Factory Method Pattern
There are more design patterns in these categories. We can dig more of them in the upcoming articles. Your support and love in the form of comments and feedback are highly appreciated. Thanks.
It would be a crime if I don't mention a book – “Design Patterns: Elements of Reusable Object-Oriented Software” written by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides in 1994, which could be considered “The Bible” of Design Patterns. If I am asked to pick only one book on software architecture and design, it would be this book. The authors of this book are often referred to as Gang of Four(GoF). If you are into C++ or love to go deeper, I highly recommend this book; not just as a one-time read, but as a reference material as well.
Shout-outs and courtesy notes
A big shout-out to the following photographers for their pictures which I could use from Unsplash and for https://miro.com/ for helping me draw the diagrams.
Photo by Anita Denunzio on Unsplash
Photo by Rhys Kentish on Unsplash
Photo by Austin Kehmeier on Unsplash
Photo by Matt Ridley on Unsplash
Photo by Nathan Dumlao on Unsplash
Photo by Alexander Grey on Unsplash
Photo by Enis Yavuz on Unsplash
Photo by Shardar Tarikul Islam on Unsplash