Adapter Pattern, Bridge Pattern, and Composite Pattern
Adapter is used to adapt the behavior/functionalities of an existing class but with a different interface.
It can be implemented by two ways, by inheritance (also called class adapter) or by composition (also called object adapter). Either we can extend the existing class and use its functionalities in new interface method, or we can use a reference of existing class in new object for using existing functionalities.
- We are making data bound UI components, which are implementing some of our proprietary interface to support the data loading/unloading. But UI components are already defined with Swing library so we want to use these and just want to bind them with data sources. Here we can extend our new components from existing Swing component and implement our data binding interface to it.
- Use of Window Adapter while intercepting the window closing event.
When to use
- Sometime in our system, we use any class/interface whose some/most of the functionalities are already defined with any other existing class. But due to system protocol, we have to use only new class probably with some new functionality. Here we can apply adapter pattern to adapt the behavior of existing class but with new interface.
- Can use the functionalities of existing classes but with new interface without re-implementing it.
- Object adapter even help to adapt the sub-class implementations of a class by simply referring it.
- Class adapter won’t work when we want to adapt a class and all of its sub classes because we need to derive the class from adapted classes while creating the new class.
It is used to separate the interface from its implementation and enables us to change either interface or implementation easily. Generally it is used to keep the client interface constant and even if we change the implementation.
It seems quite similar to adapter pattern, where we can adapt the functionalities of any other class and expose this with a separate interface. But the difference is in purpose, Adapter is implemented to use the existing implementation with a new interface but Bridge is used to separate the implementation from interface to user so that user won’t be affected by any change in implementation.
- We want to present some data to user. Based on the user profile, the data can be either in simple list form having names only or in a table having complete details. Here we can implement the logic to fetch the data and arranging it in required format in a separate class which can be accessed from user interface which could be a list, table or tree.
When to use
- When implementation of functionality can be used by multiple interfaces and we don’t want to duplicate the code for each interface.
- When we want to keep the user interface intact from any change in implementation.
- Avoid change in interface on any change in implementation
- Help to avoid the duplicate code for different interfaces having similar kind of back end requirements.
- It can prevent us to recompile the user interface on any change in implementation, but only bridge and implementation can be recompiled.
It is a collection of objects, anyone of which can be either a composite or just a primitive object. It enables us to represent a single object or a collection of objects using the same interface.
- If we are designing a runtime system structure for java program, we can implement it in a tree form where every node can be a executable piece of statement and it may have other nodes in it (which should be executed before it) or may be a leaf node, which just need to execute itself and return the result to the parent (or makes the changes in shared state cache).
- If we are designing a system to display the employee structuring of an organization. It could be in tree form or in any other form. But designing the data structure using composite pattern can easily manage the requirements for hierarchy structure, where any employee work as individual or may have a number of other employees as sub-ordinates.
When to Use
- If we need to design a tree like structure where any node can be a leaf or a composite node again, and all this can be calculated dynamically at runtime.
- When we want to make the system very generic, using a single interfaces which can accommodate a primitive as well as composite elements.
- It makes the system very generic.
- It is easy to add a new component to any existing composite structure and the existing core framework can operate on new components as well without making any modification.
- It is very easy to replace any existing component from the hierarchy.
- It results in over generic structure, which sometimes unable to enforce any validations rule on the components to be added.