Design patterns are reusable solutions for commonly occurring problems in software design world. One can think of a design pattern as a description to how developers can solve problems in different situations. However, it is not an end design that can be placed in the code and expect it to solve problems magically.
Historically, design patterns gained recognition and popularity in 1994 when the "Design Patterns: Elements of Reusable Object-Oriented Software" book was published. However, patterns originated as an architectural concept by Christopher Alexander between 1977 and 1979, and later in 1987 two of the greatest software engineers, Kent Beck and Ward Cunningham, started experimenting and applying those patterns to programming.
The Benefits Of Using Them
Design patterns help speeding up the development process, and that's because they tend to provide development paradigms that are well tested and have proven their usefulness. They are also reusable as they reflect right off the bat solutions that can be adapted to suit our needs.
Above all, they help to prevent exquisite issues that can cause extensive problems and improve code readability for developers who are familiar with the patterns. Design patterns provide general solutions, documented in a format that doesn't require specifics tied to a particular problem. Besides, they allow developers to communicate using well-known, well-understood names for software interactions.
Design Patterns Classification
"Design Patterns: Elements of Reusable Object-Oriented Software" book defined twenty-three design pattern and classified them into three categories. Those categories are Creational, Structural, and Behavioral. Let's define each one of them.
In short, those are the patterns that are used for class/object instantiation. Creating objects could introduce a complicated situation in a project. Therefore, these patterns tend to solve the problem by controlling the creation process. Their aim is to create objects and hide the creation logic, rather than instantiating objects directly. This gives more flexibility and makes those objects replaceable.
Some tend to split this category further more into two categories: class-creation patterns and object-creational patterns. The prior use inheritance in the instantiation process while the later use delegation.
Examples: Singleton, Factory, Abstract Factory and Builder Pattern.
They are about class and object composition. Structural patterns tend to ease the design by identifying a simple way to realize relationships between entities. They help ensure that when one part of a system changes, we don't have to change the rest of the system structure.
Structural class-creation patterns use inheritance to compose interfaces while structural object-patterns define ways to produce objects to obtain new functionality.
Example: Facade, Decorator, and Proxy Pattern.
They are patterns that are concerned with the communication between objects. By doing so, these patterns increase flexibility in carrying out this communication.
Examples: Startegy, Observer and Visitor Pattern.
There is a fourth type of patterns known as "Concurrency patterns" and those are the types of design patterns that deal with the multi-threaded programming paradigm.