{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Паттерн Адаптер\n", "\n", "Паттерн Адаптер, так же как и декоратор относится к структурным паттернам проектирования. Задача адаптера -- обеспечение взаимодействия между некоторым базовым класом и адаптируемым классом или группой классов. При этом интерфейс адаптируемого объекта может быть не совсестим с интерфейсом базового класса.\n", "\n", "Для обеспечения совместимости создается отдельный класс, который реализует интерфейс взаимодействия с базовым классом и использует адаптируемый. \n", "\n", "К структуре паттерна Адаптер относятся только базовый объект, адаптируемый, и сам адаптер. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Структура Адаптера\n", "\n", "\n", "\n", "Для создания адаптера необходима система и адаптируемый объект. Система взаимодействует с объектом, имеющим интерфейс Terget. Адаптер реализует этот интерфейс и взаимодействует с адаптируемым объектом.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Применение паттерна Adapter\n", "\n", "Паттерн адаптер применятся очень часто в огромном количетстве задач. Большое количество библиотек для языка Python являются адаптерами к другим библиотркам, написанным на С/С++. Использование подобных оберток позволяет увеличить производительность программ на этом языке. \n", "\n", "Кроме библиотек паттерн адаптер часто используется в модулях для работы с базами данных. Это позволяет спрятать SQL-код и пользоваться простой и понятной оболочкой.\n", "\n", "Еще адаптеры могут использоваться для сборки большого количества отдельных модулей в единую программу. Проблемы могут возникать, когда используются модули от старых проектов или написанные независимыми командами разработчиков и имеют несоглосованный интерфейс. \n", "\n", "Стоит отметить, что если есть возможность, интерфейсы следует согласовывать и не использовать паттерн Адаптер. Это улучшит читаемость кода, так как в нем не будет лишних сущностей, мешающих пониманию а так же может немного улучшить производительность, так как не будет выполняться код собственно паттерна. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Пример использования адаптера" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import re\n", "from abc import ABC, abstractmethod\n", "\n", "text = '''\n", "Design Patterns: Elements of Reusable Object-Oriented Software is a software engineering book describing software design patterns. The book's authors are Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides with a foreword by Grady Booch. The book is divided into two parts, with the first two chapters exploring the capabilities and pitfalls of object-oriented programming, and the remaining chapters describing 23 classic software design patterns. The book includes examples in C++ and Smalltalk.\n", "It has been influential to the field of software engineering and is regarded as an important source for object-oriented design theory and practice. More than 500,000 copies have been sold in English and in 13 other languages. The authors are often referred to as the Gang of Four (GoF).\n", "'''\n", "\n", "class System: # Класс, представляющий систему\n", " def __init__(self, text):\n", " tmp = re.sub(r'\\W', ' ', text.lower())\n", " tmp = re.sub(r' +', ' ', tmp).strip()\n", " self.text = tmp\n", " \n", " def get_processed_text(self, processor): # Метод, требующий на вход класс-обработчик\n", " result = processor.process_text(self.text) # Вызов метода обработчика\n", " print(*result, sep = '\\n')\n", "\n", "class TextProcessor: # Абстрактный интерфейс обработчика\n", " @abstractmethod\n", " def process_text(self, text):\n", " pass\n", " \n", "class WordCounter: # Обработчик, несовместимый с основной системой\n", " def count_words(self, text):\n", " self.__words = dict()\n", " for word in text.split():\n", " self.__words[word] = self.__words.get(word, 0) + 1\n", " \n", " def get_count(self, word):\n", " return self.__words.get(word, 0)\n", " \n", " def get_all_words(self):\n", " return self.__words.copy()" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "the\n", "and\n", "software\n", "design\n", "of\n", "book\n", "patterns\n", "object\n", "oriented\n", "is\n", "in\n", "a\n", "engineering\n", "describing\n", "authors\n", "are\n", "with\n", "two\n", "chapters\n", "been\n", "to\n", "as\n", "elements\n", "reusable\n", "s\n", "erich\n", "gamma\n", "richard\n", "helm\n", "ralph\n", "johnson\n", "john\n", "vlissides\n", "foreword\n", "by\n", "grady\n", "booch\n", "divided\n", "into\n", "parts\n", "first\n", "exploring\n", "capabilities\n", "pitfalls\n", "programming\n", "remaining\n", "23\n", "classic\n", "includes\n", "examples\n", "c\n", "smalltalk\n", "it\n", "has\n", "influential\n", "field\n", "regarded\n", "an\n", "important\n", "source\n", "for\n", "theory\n", "practice\n", "more\n", "than\n", "500\n", "000\n", "copies\n", "have\n", "sold\n", "english\n", "13\n", "other\n", "languages\n", "often\n", "referred\n", "gang\n", "four\n", "gof\n" ] } ], "source": [ "class WordCounterAdapter(TextProcessor): # Адаптер к обработчику\n", " def __init__(self, adaptee): # В конструкторе указывается, к какому объекту следует подключить адаптер \n", " self.adaptee = adaptee\n", " \n", " def process_text(self, text): # Реализация интерфейса обработчика, требуемого системой.\n", " self.adaptee.count_words(text)\n", " words = self.adaptee.get_all_words().keys()\n", " return sorted(words, key = lambda x: self.adaptee.get_count(x), reverse = True)\n", "\n", "system = System(text)\n", "counter = WordCounter()\n", "adapter = WordCounterAdapter(counter)\n", "system.get_processed_text(adapter)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.5" } }, "nbformat": 4, "nbformat_minor": 2 }