---
title: "SP1 - Adapter - Learn Design Pattern From Simple Things"
description: "Having many devices that need to connect to your Macbook leads to too many cables. You need a tool to replace all those cables."
pubDate: "2022-10-15"
lang: "en"
slug: "sp1-adapter-learn-design-pattern-from-simple-things"
url: "https://hoangyell.com/sp1-adapter-learn-design-pattern-from-simple-things/"
author: "HoangYell"
categories: ["Software Craft"]
tags: ["design-patterns", "structural-patterns"]
heroImage: "https://raw.githubusercontent.com/HoangGeek/store/main/webp/vTFProK.webp"
---

_Adapter is a **structural** design pattern:_
🖤🖤🖤🖤🖤

## What is Adapter?

Adapter is a set of converters(`USB-B to USB-C`, `USB-A to USB-C`, `HDMI to USB-C`).

Adapter makes it possible for the main device (`Macbook`) to be connected to incompatible devices (``, ``, ``)

![Image](https://raw.githubusercontent.com/HoangGeek/store/main/webp/202238106-a587babd-e4c6-4435-a6e5-8691d8215620.webp)

## Why use Adapter?
It's all in one converter, neat and clean

_Use Adapter:_
![Image](https://raw.githubusercontent.com/HoangGeek/store/main/webp/section-4-mobile-v2.webp)

**Question:** _I hate the Adapter, what are the alternatives?_

**Answer:** _You can buy separate converters(`USB type B to type C` cable, `USB type A to type C` cable, `HDMI to type C` cable) for replacement!_

_Use Many Converters:_
![Image](https://raw.githubusercontent.com/HoangGeek/store/main/webp/EUq9YdUU4AA6Mfi.webp)

## When to use Adapter?
**Question:** _When I need a `USB type C Adapter`?_

**Answer:** _When you need to connect `Printer, Flash or Monitor` to `Macbook`, right?_

### Input:
  - Having a Macbook, that only have the USB type C port.
  - Having incompatible (non-USB type C) devices:
    - `Printer (USB type B)`
    - `Flash (USB type A)`
    - `Monitor (HDMI)`
``` python
# Input 2: Having incompatible (non-USB type C) devices:
class Printer:
    name = "Printer"

    def connect_usb_b(self):
        return f"{self.name} is connected: Printing..."

# Input 2: Having incompatible (non-USB type C) devices:
class Flash:
    name = "Flash"

    def connect_usb_a(self):
        return f"{self.name} is connected: Copying..."

# Input 2: Having incompatible (non-USB type C) devices:
class Monitor:
    name = "Monitor"

    def connect_hdmi(self):
        return f"{self.name} is connected: Displaying..."
```
### Expected Output:
  - Making that non-USB type C devices have USB type C port
    - `Printer (USB type C)`
    - `Flash (USB type C)`
    - `Monitor (USB type C)`
  - MacBook is able to connect to those incompatible devices
``` shell
Printer is connected: Printing...
Flash is connected: Copying...
Monitor is connected: Displaying...
```

## How to implement Adapter?

### Non-Adapter implementation:
``` python
if __name__ == "__main__":
    devices = [Printer(), Flash(), Monitor()]
    for device in devices:
        if isinstance(device, Printer):
            # Expected Output 2: MacBook is able to connect to those incompatible devices
            print(device.connect_usb_b())
        elif isinstance(device, Flash):
            # Expected Output 2: MacBook is able to connect to those incompatible devices
            print(device.connect_usb_a())
        elif isinstance(device, Monitor):
            # Expected Output 2: MacBook is able to connect to those incompatible devices
            print(device.connect_hdmi())
```

### Adapter Implementation:
``` python
class Adapter:
    def __init__(self, obj, **adapted_methods):
        self.obj = obj
        self.__dict__.update(adapted_methods)

    def __getattr__(self, attr):
        return getattr(self.obj, attr)

if __name__ == "__main__":
    devices = []
    printer = Printer()
    # Expected Output 1: Making that non-USB type C devices have USB type C port
    devices.append(Adapter(printer, connect=printer.connect_usb_b))
    flash = Flash()
    # Expected Output 1: Making that non-USB type C devices have USB type C port
    devices.append(Adapter(flash, connect=flash.connect_usb_a))
    monitor = Monitor()
    # Expected Output 1: Making that non-USB type C devices have USB type C port
    devices.append(Adapter(monitor, connect=monitor.connect_hdmi))
    for device in devices:
        # Expected Output 2: MacBook is able to connect to those incompatible devices
        print(device.connect())
```

[Source Code](https://github.com/HoangYell/Design-Pattern-From-Simple-Things/blob/main/sp1_adapter.py)
