Шаблоны проектирования Python — шаблон адаптера

задняя часть база данных Python Шаблоны проектирования

问题: Предположим, есть программная система, которую вы хотите использовать с библиотекой классов нового поставщика без изменения существующего кода, но интерфейс нового поставщика отличается от интерфейса старого поставщика.

Эта проблема аналогична проблеме ниже

Вилки американского стандарта 🔌 нельзя использовать в розетках европейского стандарта, какова обычная практика?

Добавьте штепсельный адаптер, функция адаптера состоит в том, чтобы преобразовать европейскую вилку в розетку США, чтобы можно было использовать вилку США.

решение

Итак, столкнувшись с библиотекой классов с совершенно новым интерфейсом без изменения существующего кода, первое, что приходит в голову, — это добавить переходник между двумя системами.

простой пример

Есть система, которая требует объект утка🦆, но сейчас есть только объект индейка🦃. Функциональность объектов утка и индейка кратко описана следующим образом:


# 鸭子的简单描述
class Duck:
    def quack(self):
        # 会呱呱叫
        print("Quack")
    
    def fly(self):
        # 飞的能力
        print("I'm flying")
        
# 火鸡的简单描述
class Turkey:
    def gobble(self):
        # 不会呱呱叫,只会咯咯叫
        print("Gobble gobble")
    
    def fly(self):
        # 飞的能力 但是飞不远
        print("I'm flying a short distance")
    

Поскольку сейчас нет объекта «утка», можно олицетворять только объект «индюк». Из-за различных функций объектов утки и объектов индейки их нельзя использовать напрямую.Теперь вам нужно использовать адаптер для выполнения этой функции:

class TurkeyAdapter(Duck):
    turkey = Turkey()  # 这里实际使用的是火鸡对象
    
    # 实现鸭子对象拥有的quack方法
    def quack(self):
        self.turkey.gobble()
    
    def fly(self):
        # 假设火鸡比鸭子飞的短,为了模拟鸭子的动作,多飞几次
        for i in range(5):
            turkey.fly()

Последующие вызовы могут использовать объект, адаптированный для индейки, например объект утка.

# test

duck = Duck()
duck.quack()
duck.fly()

turkey_adapter = Duck()
turkey_adapter.quack()
turkey_adapter.fly()

Теперь давайте посмотрим на процесс использования адаптера:

  1. Клиент вызывает адаптер через интерфейс, реализованный адаптером.
  2. Адаптер преобразует запрос в запрос, на который адаптируемая сторона может ответить.
  3. Адаптер отвечает, возвращая результат адаптеру, который, в свою очередь, отвечает клиенту.

На этом примере давайте взглянем на формальное определение шаблона адаптера.

определение

适配器模式:Преобразуйте интерфейс класса в другой интерфейс, ожидаемый клиентом. Адаптеры позволяют классам с другими несовместимыми интерфейсами взаимодействовать.

преимущество

  • Преобразование интерфейса можно выполнить, создав адаптеры, сделав несовместимые интерфейсы совместимыми и позволив клиентам отделиться от реализованных интерфейсов.
  • Используйте композицию объектов, чтобы обернуть адаптируемый интерфейс модифицированным интерфейсом.
  • Адаптированный подкласс можно использовать с адаптером
  • Удовлетворить принципу открытия/закрытия

开放/封闭原则Это один из основных принципов объектно-ориентированного проектирования, утверждающий, что программный объект должен быть открыт для расширения и закрыт для модификации.

Адаптеры в реальном мире

  • xmltodict может конвертировать xml в json
  • grpc также можно рассматривать как адаптер, обеспечивающий возможность межъязыкового вызова.
  • sqlalchemy может подключаться к нескольким базам данных без изменения кода

Примеры в этой статье взяты из "Шаблоны проектирования Head First".


Наконец, поблагодарите мою девушку за ее поддержку и терпимость, чем ❤️

Вы также можете ввести следующие ключевые слова в официальном аккаунте, чтобы получить исторические статьи:公号&小程序 | 设计模式 | 并发&协程