Easy patterns: Adapter
This article is created in continuation to series of easy patterns description and describes structural pattern for making possible working together for classes that are not compatible initially.
Currently you can find articles for such patterns:
Creational patterns:
Structural patterns:
Adapter (this article)
Behavioral patterns:
The main essence
This pattern is also known as wrapper. It wraps incompatible class to work with other classes in the system. This pattern includes three main roles:
- target — defines destination point that would use adapted interface
- adapter — collaborates with a target conforming desired interface
- adaptee — defines an existing interface that needs adapting
Example of use
In this example we’re creating storage that can keep users in memory and render some table with all users. Each user can give the storage only name and age fields, but fields like id, first name letter and method to return profile data are also needed. So, we passed wrapped each user in adapter class to get extra functionality.
Also we could not pass user instance to wrapped class, but just extend adapter class from User class. In this case adapter extends initial fields from adaptee class and adds some new ones. In our current example it’s easy to hide unwanted props and methods and add new, needed by target class.
Profit
It helps to adapt one class to work with other classes. This pattern also helps to extend adaptee logic with extra functionality. It provides only one one type of object to work in the system, no extra points of indirection are needed.
Weak places
It hides implementation of adaptee by inheritance. Each adapter needs specific adaptee and can’t be unified to work with other adaptee types. However it’s possible to make two-way adapters — class that makes communication more transparent by implementing specific interface to each target that interested in this adapter.
Conclusion
If you found this article helpful, please hit the 👏 button and feel free to comment below!