Main difference is:Decorator is used to decorate individual objects at run-time. Adapter is used to add features to the class and therefore to ALL of its objects. It's true that Adapter targets the class and therefore to ALL of its objects.
The primary difference between the adapter pattern and the facade pattern is that the adapter pattern lets you cope with change in a sub-system after the change has occurred while the facade pattern lets you plan for changes to a sub-system.
Adapter pattern works as a bridge between two incompatible interfaces. This type of design pattern comes under structural pattern as this pattern combines the capability of two independent interfaces.
In software engineering, the adapter pattern is a software design pattern (also known as wrapper, an alternative naming shared with the decorator pattern) that allows the interface of an existing class to be used as another interface.
"Adapter makes things work after they're designed; Bridge makes them work before they are. [GoF, p219]"
Effectively, the Adapter pattern is useful when you have existing code, be it third party, or in-house, but out of your control, or otherwise not changeable to quite meet the interface you need it to. For instance, we have a SuperWeaponsArray which can control a fine array of doomsday devices.
public class SuperWeaponsArray {
/*...*/
public void destroyWorld() {
for (Weapon w : armedWeapons) {
w.fire();
}
}
}
Great. Except we realize we have a nuclear device in our arsenal that vastly predates the conversion to the Weapon interface. But we'd really like it to work here... so what do we do... wedge it in!
NukeWeaponsAdaptor - based off of our Nuke class, but exporting the Weapon interface. Sweet, now we can surely destroy the world. It seems like bit of a kludge, but it makes things work.
The Bridge pattern is something you implement up front - if you know you have two orthogonal hierarchies, it provides a way to decouple the interface and the implementation in such a way that you don't get an insane number of classes. Let's say you have:
MemoryMappedFile and DirectReadFile types of file objects. Let's say you want to be able to read files from various sources (Maybe Linux vs. Windows implementations, etc.). Bridge helps you avoid winding up with:
MemoryMappedWindowsFile MemoryMappedLinuxFile DirectReadWindowsFile DirectReadLinuxFile
http://en.wikipedia.org/wiki/Adapter_pattern
The Adapter pattern is more about getting your existing code to work with a newer system or interface.
If you have a set of company-standard web service APIs that you'd like to offer to another application's existing extensibility interface, you might consider writing a set of adapters to do this. Note that there's a grey area and this is more about how you technically define the pattern, since other patterns like the facade are similar.
http://en.wikipedia.org/wiki/Bridge_pattern
The Bridge pattern is going to allow you to possibly have alternative implementations of an algorithm or system.
Though not a classic Bridge pattern example, imagine if you had a few implementations of a data store: one is efficient in space, the other is efficient in raw performance... and you have a business case for offering both in your app or framework.
In terms of your question, "where I can use which pattern," the answer is, wherever it makes sense for your project! Perhaps consider offering a clarification edit to guide the discussion on where you believe you need to use one or the other.
Adapter:
UML Diagram: from dofactory article:
Target : defines the domain-specific interface that Client uses.
Adapter : adapts the interface Adaptee to the Target interface.
Adaptee : defines an existing interface that needs adapting.
Client : collaborates with objects conforming to the Target interface.
Example:
Square and Rectangle are two different shapes and getting area() of each of them requires different methods. But still Square work on Rectangle interface with conversion of some of the properties.
public class AdapterDemo{
public static void main(String args[]){
SquareArea s = new SquareArea(4);
System.out.println("Square area :"+s.getArea());
}
}
class RectangleArea {
public int getArea(int length, int width){
return length * width;
}
}
class SquareArea extends RectangleArea {
int length;
public SquareArea(int length){
this.length = length;
}
public int getArea(){
return getArea(length,length);
}
}
Bridge:
EDIT: ( as per @quasoft suggestion)
You have four components in this pattern.
Abstraction: It defines an interface
RefinedAbstraction: It implements abstraction:
Implementor: It defines an interface for implementation
ConcreteImplementor: It implements Implementor interface.
Code snippet:
Gear gear = new ManualGear();
Vehicle vehicle = new Car(gear);
vehicle.addGear();
gear = new AutoGear();
vehicle = new Car(gear);
vehicle.addGear();
Related post:
When do you use the Bridge Pattern? How is it different from Adapter pattern?
Key differences: from sourcemaking article
This post has been around for quite a while. However, it is important to understand that a facade is somewhat similar to an adapter but it's not quite the same thing. An adapter "adapts" an existing class to a usually non-compatible client class. Let's say that you have an old workflow system that your application is using as a client. Your company could possibly replace the workflow system with a new "incompatible" one (in terms of interfaces). In most cases, you could use the adapter pattern and write code that actually calls the new workflow engine's interfaces. A bridge is generally used in a different way. If you actually have a system that needs to work with different file systems (i.e. local disk, NFS, etc.) you could use the bridge pattern and create one abstraction layer to work with all your file systems. This would basically be a simple use case for the bridge pattern. The Facade and the adapter do share some properties but facades are usually used to simplify an existing interface/class. In the early days of EJBs there were no local calls for EJBs. Developers always obtained the stub, narrowed it down and called it "pseudo-remotely". This often times caused performance problems (esp. when really called over the wire). Experienced developers would use the facade pattern to provide a very coarse-grained interface to the client. This facade would then in turn do multiple calls to different more fine-grained methods. All in all, this greatly reduced the number of method calls required and increased performance.
In the top answer, @James quotes a sentence from the GoF, page 219. I think it's worthwhile reproducing the full explanation here.
Adapter versus Bridge
The Adapter and Bridge patterns have some common attributes. Both promote flexibility by providing a level of indirection to another object. Both involve forwarding requests to this object from an interface other than its own.
The key difference between these patterns lies in their intents. Adapter focuses on resolving incompatibilities between two existing interfaces. It doesn't focus on how those interfaces are implemented, nor does it consider how they might evolve independently. It's a way of making two independently designed classes work together without reimplementing one or the other. Bridge, on the other hand, bridges an abstraction and its (potentially numerous) implementations. It provides a stable interface to clients even as it lets you vary the classes that implement it. It also accommodates new implementations as the system evolves.
As a result of these differences, Adapter and Bridge are often used at different points in the software lifecycle. An adapter often becomes necessary when you discover that two incompatible classes should work together, generally to avoid replicating code. The coupling is unforeseen. In contrast, the user of a bridge understands up-front that an abstraction must have several implementations, and both may evolve independently. The Adapter pattern makes things work after they're designed; Bridge makes them work before they are. That doesn't mean Adapter is somehow inferior to Bridge; each pattern merely addresses a different problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With