The Adapter Design Pattern is a structural pattern that allows incompatible interfaces to work together. It acts as a bridge between two incompatible interfaces, enabling them to collaborate seamlessly without modifying their existing code.The adapter plays the role of converter or translator.
This pattern is particularly useful when integrating new components or systems that have different interfaces from the ones already in use.
To handle the incompatibility, we use different approaches, and based on that, we can classify the Adapter Pattern into 2 parts.
- Object Adapter Pattern
- Class Adapter Pattern
Object Adapter Design Pattern
In Object Adapter Pattern, Incompatibility is handled by creating the object.
Class Adapter Design Pattern
Class Adapter Design Pattern Incompatibility is handled by inheritance.
Components of Adapter Design Pattern
- Target: The interface that is expected by the client code.
- Adaptee: The existing class or interface that needs to be integrated into the system but has an incompatible interface with the Target.
- Adapter: The class that bridges the gap between Target and Adaptee by implementing the Target interface and internally using the Adaptee.
Example in C#:
Let's consider a scenario where we have an OldPrinter class with a method PrintOld(), and we want to integrate it into a system that expects a different interface, say INewPrinter with PrintNew() method.In this example, the PrinterAdapter class implements the INewPrinter interface by internally using the OldPrinter class.
- Adaptee: Existing class with an incompatible interface.
12345678910
namespace
AdapterPattern.Adaptee
{
public
class
OldPrinter
{
public
void
PrintOld()
{
Console.WriteLine(
"Printing with the old printer."
);
}
}
}
- Target: New interface expected by the client.
1234567
namespace
AdapterPattern.Target
{
public
interface
INewPrinter
{
void
PrintNew();
}
}
- Adapter: Bridges the gap between OldPrinter and INewPrinter.
12345678910111213141516171819202122
using
AdapterPattern.Adaptee;
using
AdapterPattern.Target;
namespace
AdapterPattern.Adapter
{
// Adapter: Bridges the gap between OldPrinter and INewPrinter
public
class
PrinterAdapter : INewPrinter
{
private
readonly
OldPrinter oldPrinter;
public
PrinterAdapter(OldPrinter oldPrinter)
{
this
.oldPrinter = oldPrinter;
}
public
void
PrintNew()
{
// Call the old printer's method through the adapter
oldPrinter.PrintOld();
}
}
}
- Client: The client code interacts with the INewPrinter interface, which internally calls the methods of the OldPrinter class through the adapter..
123456789101112
using
AdapterPattern.Adaptee;
using
AdapterPattern.Adapter;
using
AdapterPattern.Target;
OldPrinter oldPrinter =
new
OldPrinter();
// Adapter to use OldPrinter as a NewPrinter
INewPrinter adaptedPrinter =
new
PrinterAdapter(oldPrinter);
// Using the NewPrinter interface
adaptedPrinter.PrintNew();
Console.ReadLine();
Output
Advantages of the Adapter Pattern:
- Interoperability: Allows integration of incompatible interfaces.
- Reusability: Existing classes can be used in new systems without modifying their code.
- Maintainability: Helps in keeping existing code intact while adapting to new requirements.
The Adapter Design Pattern is a powerful tool for integrating diverse components or systems with different interfaces, promoting flexibility and maintainability in software design.
The full source code is available here:
Happy coding!! 😊
No comments:
Post a Comment