Short: They help us solve recurring design problems. Note that : design patterns don’t solve the problem themselves, they help us solve the problem.
- Communication, Learning and Enhanced Insight: Over the last decade design patterns have become part of every developer’s vocabulary. This really helps in communication. One can easy tell another developer on the team, “I’ve used Command pattern here” and the other developer understands not just the design, but can also easily figure out the rationale behind it. Design Patterns really help in learning, esp. when you are new on a project. Also this helps in providing developers with better insight about parts of the application or 3rd party frameworks they use.
- Decomposing System into Objects : The hard part about OO Design is finding the appropriate objects and decomposing a system. One has to think about encapsulation, granularity, dependencies, flexibility, performance, evolution, reusability and so on. They all influence decomposition, often in conflicting ways. Design Patterns really helps identify less obvious abstractions. These objects are seldom found during analysis or even the early design, they’re discovered later in the course of making a design more flexible and reusable.
- Determining Object Granularity: One thing I struggle a lot with is finding the right level of abstraction and granularity. Design patterns helps in coming up with objects with different levels of granularity that makes sense.
- Specifying Object Interface : Identifying the right interface and the relationship between various interface is not a one-shot activity. Usually it takes several iterations to identify the right composition of interfaces. Forget interfaces, most of the times, coming up with a method signature can also be quite tricky. Design Patterns really helps in this area.
- Specifying Object Implementation : How should we implement an Object? Given an interface there could be multiple concrete classes of that type, each one can have very different implementations. Design Patterns provide guidance like Program to an interface (type) not an implementation (concrete class) which can result in really good OO code.
- Ensuring right reuse mechanism : When to use Inheritance, when to use Composition, when to use Parameterized Types? Is delegation the right design decision in this context? There are various questions that comes to a programmer’s mind when they are trying to design highly reusable and maintainable code. Knowledge of design patterns can really come handy when making such decisions.
- Relating run-time and compile time structures : An object oriented program’s run-time structure often bares little resembles to this code structure. Sometimes looking at the code does not give us the insights into run-time structure. Knowledge of design patterns can make some of the hidden structure obvious.
- Designing for change : We all know that lack of continuous refactoring and design that doesn’t take change into account risks major redesign in the future. Over the years we’ve also learnt that big upfront designs can’t standup against the constant change/additon of software requirements. We’ve leant grouping elements with similar change life cycle together yields in far more flexible and extendable design. If we think some behavior or element of behavior is most likely to change, we try to abstract that behavior in one place. While we understand these concepts are important design patterns really make it possible to design such systems. Each design pattern lets some aspect of the system structure vary independently of other aspects, thereby making a system more robust to a particular kind of change.