Introduction to Design Patterns
In this tutorial, we will introduce design patterns, which is one of the hottest and most respected concepts. You must know design patterns to develop quality programs and true object-oriented software. We start with the first step of the design patterns to the world of software developers. Secondly, we mention solving a problem with design patterns. After that, we give information about some problems that are modeled with design patterns. Next, we give some mostly used design patterns by their categories and finally summarize the tutorial in the last section.
What is a design pattern?
An architect named Christopher Alexander caused the entrance of the concept of “Design Patterns” to the software world. He developed this concept while working on the architectural features in the buildings that have been built by humans for centuries. Here is what Alexander says about the design patterns: “Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice.“ If we explain this definition: Each pattern stands for a problem that happens repeatedly, and it gives a core solution for this problem. So you can use this solution a million times in your projects, without doing the same things.
Why use design patterns?
A design pattern is a generic, abstract and reusable solution to a common problem. Design patterns are abstract, this means developers describe them at the design level, not at the language level. Therefore, we often use class and sequence diagrams to express design patterns. Since design patterns are abstract, we give their shapes according to our needs while using them.
Before passing through design patterns, we should understand “Low coupling” and “High cohesion” concepts first.
Low coupling: Coupling term stands for the relationship between more than one class/object. In object-oriented languages, accessing one class to another is realized by inheritance or by linking a class to another class with a reference.
In the concept of strict coupling, changes of a class in a relationship can affect other linked classes as well. So the relationship between objects should not be tight and should be loosely coupled. Such that changes made in one class do not spread to other classes.
A low coupled code example is given below. There is no dependency between the Box and the Volume classes. If we change something in one class we do not have to change anything in the other class.
class Volume { public static void main(String args[]) { Box b = new Box(5,5,5); System.out.println(b.getVolume()); } } final class Box { private int volume; Box(int length, int width, int height) { this.volume = length * width * height; } public int getVolume() { return volume; } }
High cohesion: Cohesion term refers to the principle of a class must only perform a single task under the single responsibility. If there are procedures that do more than one different job or independent data fields in a class, these workgroups should be separated into different classes. If the procedures in a class do not use common data fields or are completely separate in terms of the work they do, it makes no sense to have them in the same set. A high cohesive code example is given below. In this example Name, Age, and Number classes have their getter functions/responsibilities inside and the responsibility of the Display class is to print the information: class Name { String name; public String getName(String name) { this.name = name; return name; } } class Age { int age; public int getAge(int age) { this.age = age; return age; } } class Number { int mobileno; public int getNumber(int mobileno) { this.mobileno = mobileno; return mobileno; } } class Display { public static void main(String[] args) { Name n = new Name(); System.out.println(n.getName(“Geeksforgeeks”)); Age a = new Age(); System.out.println(a.getAge(10)); Number no = new Number(); System.out.println(no.getNumber(1234567891)); } } Design patterns help us find the right responsibilities and distribute them to objects by considering high cohesion and construct objects in a way that has low coupling.
Problems modeled with design patterns
In this section we mention some of the problems that design patterns model are as follows:
- Creating objects
- Creating complex objects
- Creating object families
- Creating only one or a certain number of objects from a class
- Controlling access to objects
- Designing the part and the whole relationship between objects
- Expressing many ways to do the same job
- Manage the communication between objects
- Qualifying an object at runtime
- Managing objects with complex states
- Keeping the state of the object and then reaching it again
- Managing multiple objects
- Applying the same job to multiple objects
A design pattern has four components
- Name: This component allows us to distinguish the problem from its solution. Therefore, the names of the patterns are important and are often given by their founder.
- Problem: It refers to which state and how the design pattern emerged. It is usually given as a verbal expression.
- Solution: It describes how the pattern solves the problem, used parts, and relationships between them.
- Result: Patterns both provide some gains and cause some losses in return. Results express them in detail.
We learn design patterns for the following purposes:
- Not reinventing the wheel, using existing proven solutions: Design patterns reveal reusable, proven models for the problems that we have mentioned and not counted above.
- Creating a formal and common language: Design patterns point to a formal pattern language. This language spreads among software developers, facilitating understanding and increasing expressiveness.
- Achieving high abstraction power for the design, getting out of the details, and thinking about the terms of higher goals. In this sense, design patterns are one of the basic requirements of being a better software developer or even engineer.
Categories of Design Patterns
There are 23 patterns in 3 different categories.
Creational design patterns
- Singleton
- Factory Method
- Abstract Factory
- Prototype
- Builder
Structural design patterns
- Adapter
- Facade
- Proxy
- Bridge
- Composite
- Decorator
- Flyweight
Behavioral design patterns
- Strategy
- Command
- Observer
- İnterpreter
- Chain of Responsibility
- State
- Visitor
- Template Method
- Mediator
Summary
Design patterns are solutions to the common problems that software developers encounter. We explain why and when to use design patterns in the software world in this tutorial. We give some common problems modeled with them and four main components of a design pattern. In the last section, we give the names of the design patterns in categories.
Other useful articles:
- 10 Java Interview Questions You Must Learn
- TOP-10 Basic Java Interview Questions
- Intermediate Java Interview Questions
- Detailed Java Interview Questions
- TOP-10 Elementary Java Interview Questions
- OOPS Concept Java Interview Questions
- TOP-5 Java Operators Interview Questions
- TOP-5 Java Streams Interview Questions
- Introduction to Design Patterns
- Creational Design Patterns
- Structural Design Patterns
- Behavioral Design Patterns