In my last article, I discussed the Strategy pattern, which falls under the Behavioural Design Pattern. The Adaptor pattern is classified under the Structural design pattern by GoF. Strategy design patterns focus on organizing and composing classes or objects to form larger structures while keeping those structures flexible and efficient.
Structural design patterns are a subset of design patterns in software engineering that focus on organizing and composing classes or objects to form larger structures while keeping those structures flexible and efficient. These patterns help developers create clear, maintainable, and reusable code by defining how objects and classes can interact and be structured in a system.
What is Adaptor pattern?
Adaptor pattern allows objects with incompatible interfaces to work together. This pattern is typically used when you want to integrate a new or existing class into a system but its interface doesn't match the one you need.
USB adaptors are real-world examples where using an adaptor/converter we make incompatible interfaces to work on Laptops or workstations.
The Adapter pattern involves creating a new class, known as the "adapter," that acts as an intermediary between two incompatible interfaces. It "adapts" the interface of one class to make it compatible with the interface expected by the client code.
An adaptor pattern provides an interface between two unrelated entities so that they can work together. Convert the interface of a class into another interface clients expect. The adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.
The Adapter pattern is useful in various scenarios, such as:
When you want to use a class from a third-party library that has an interface incompatible with your code.
When you want to reuse existing classes but need them to work together with new classes.
When you want to create a layer to provide additional functionality to a class without modifying its code (e.g., logging, security, etc.).
Let's try to understand the Adaptor pattern with the help of a simple example. Consider we are working on a project related to USB devices. We've defined the interface for USB Port and regular USB type B works well.
class UsbCable:
def __init__(self):
self.isPlugged = False
def plugUsb(self):
self.isPlugged = True
class UsbPort:
def __init__(self):
self.isPortAvailable = True
def plug(self, usb):
if self.isPortAvailable:
usb.plugUsb()
self.isPortAvailable = False
# UsbCables can plug directly into usb port
usbCable = UsbCable()
usbPort1 = UsbPort()
usbPort1.plug(usbCable)
A few months later we were assigned the task of supporting a micro USB cable but our USB port was not compatible with this USB type. In this case, we will write MicroToUsbAdaptor class which does the necessary conversion to make it compatible with the existing port.
class MicroUsbCable:
def __init__(self):
self.isPlugged = False
def plugMicroUsb(self):
self.isPlugged = True
# Above cable is not compatible with UsbPort. To solve this we can create micro to usb adaptor
class MicroToUsbAdaptor(UsbCable):
def __init__(self, microUsbCable):
self.microUsbCable = microUsbCable
self.microUsbCable.plugMicroUsb()
# we can override UsbCable.plugUsb() if needed.
# MicroUsbCable can plug into Usb Ports via an adapter
microToUsbAdapter = MicroToUsbAdaptor(MicroUsbCable())
usbPort2 = UsbPort()
usbPort2.plug(microToUsbAdapter)
Comments