Шаблоны, или паттерны программирования - это повторяющиеся решения типовых задач, возникающих в процессе разработки программного обеспечения. Паттерны проектирования были созданы, чтобы обеспечить более легкую переносимость, легкость поддержки, улучшение расширяемости и многоразовое использование кода.
Паттерны проектирования можно разделить по трем типам:
- Паттерны порождающего типа (Creational patterns): отвечают за удобное и безопасное создание новых объектов или инстанцирование классов используя наследование или композицию.
- Паттерны структурного типа (Structural patterns): позволяют определять отношения между различными элементами системы для создания более сложных структур.
- Паттерны поведенческого типа (Behavioral patterns): определяют взаимодействие между объектами и классами системы и делятся на уровни объектов, классов и взаимодействующих объектов и классов.
Некоторые примеры паттернов проектирования включают в себя:
- Одиночка (Singleton): гарантирует, что существует только один экземпляр класса и обеспечивает глобальную точку доступа к этому экземпляру.
- Фабричный метод (Factory Method): упрощает создание объектов и позволяет избежать прямого связывания между создаваемыми объектами и объектами, которые их используют.
- Шаблонный метод (Template Method): определяет скелет алгоритма в суперклассе и делегирует отдельные шаги выполнения дочерним классам.
- Мост (Bridge): разделяет абстракцию и ее реализацию, позволяя им развиваться независимо.
- Итератор (Iterator): предоставляет доступ к элементам коллекции без определения их внутренней структуры.
- Наблюдатель (Observer): предоставляет объектам возможность реагировать на изменения объекта, на который они подписаны.
- Адаптер (Adapter): позволяет совместно использовать несовместимые объекты или классы. Существует множество других паттернов проектирования, которые разработчики могут использовать в своём проекте в зависимости от задачи и контекста.
Вот пять наиболее популярных паттернов проектирования в Python:
1. MVC (Model-View-Controller)
MVC (Model-View-Controller) - это популярный паттерн проектирования программного обеспечения, который используется для разделения приложения на три основных компонента: модель (Model), представление (View) и контроллер (Controller). Этот подход позволяет упростить разработку, тестирование и сопровождение приложения, а также повысить его гибкость, масштабируемость и переносимость.
ссылка на код (gist github MVC.py)
Модель (Model) представляет собой компонент приложения, который отвечает за хранение данных и логику их обработки. Она не зависит от других компонентов и может использоваться в различных контекстах. Модель может быть представлена в виде классов, структур или баз данных.
Представление (View) - это компонент, который отвечает за отображение данных пользователю. Она не содержит логики и не взаимодействует напрямую с моделью. Представление может быть представлено в виде графического интерфейса, веб-страницы или другого типа пользовательского интерфейса.
Контроллер (Controller) - это компонент, который управляет взаимодействием между моделью и представлением. Он получает запросы от пользователя через представление, обрабатывает их с помощью модели и возвращает результат обратно в представление. Контроллер может изменять состояние модели и обновлять представление в соответствии с этим состоянием.
2. Фабричный метод (Factory Method)
Фабричный метод (Factory Method) - это порождающий паттерн проектирования, который позволяет создавать объекты без указания их конкретных классов. Вместо этого он предоставляет интерфейс для создания объектов в суперклассе, который может быть переопределен в подклассах для изменения типа создаваемого объекта.
ссылка на код (gist github AnimalFactory.py)
В этом примере Animal является суперклассом, который определяет абстрактный метод speak(). Dog и Cat - это подклассы, которые реализуют этот метод и возвращают соответствующий звук животного.
AnimalFactory - это фабричный метод, который создает объекты Dog или Cat в зависимости от переданного типа.
Когда factory.create_animal("Dog") вызывается, он создает объект типа Dog и возвращает его. Аналогично, при вызове factory.create_animal("Cat"), он создает объект типа Cat и возвращает его.
Таким образом, фабричный метод позволяет создавать объекты, не указывая их конкретных классов, что делает код гораздо более гибким и расширяемым.
3. Стратегия (Strategy)
Стратегия (Strategy) - это поведенческий паттерн проектирования, который позволяет определить семейство алгоритмов, инкапсулировать каждый из них и сделать их взаимозаменяемыми. Таким образом, данный паттерн позволяет изменять поведение объекта в зависимости от выбранного алгоритма.
Основные участники паттерна:
- Контекст (Cоntеxt)- объект, который содержит ссылку на объект конкретной стратегии.
- Стратегия (Strategy) - интерфейс, который определяет операции, которые должны быть реализованы в каждом конкретном алгоритме.
- Конкретная стратегия (Concrete Strategy) - класс, который реализует интерфейс стратегии и содержит конкретный алгоритм.
Пример использования данного паттерна может быть в задаче сортировки массива. Контекст в данном случае - это сам массив, который нужно отсортировать. Стратегия - это интерфейс, определяющий метод сортировки. Конкретные стратегии - это классы, которые реализуют интерфейс стратегии и содержат конкретные алгоритмы сортировки (например, сортировка пузырьком, быстрая сортировка и т.д.).
Использование данного паттерна позволяет уменьшить связность между классами, что позволяет упростить поддержку и разработку кода.
ссылка на код (gist github Strategy.py)
4. Фасад (Facade)
Паттерн Фасад (Facade) – это структурный паттерн проектирования, который позволяет скрыть сложность и множество интефейсов системы путем предоставления простого объединенного интерфейса. Название этого паттерна происходит от фасада здания – его фронтальной стены. Фасад не дает никакой информации об устройстве здания за ней. Так же фасад программного приложения скрывает внутреннюю сложность системы и предоставляет упрощенный интерфейс для доступа к ее функционалу.
Пример использования фасада может быть следующим: пользователь взаимодействует с веб-сайтом, который оказывает различные услуги, такие как онлайн-покупки, онлайн-банкинг и т.д. Внутри сайта есть много сложных программных компонентов, подразделений и работ, которые необходимы для обеспечения этих услуг, но пользователь не должен быть знаком с этими деталями, а должен иметь возможность использовать только разработанный интерфейс.
Применение Фасада имеет следующие преимущества:
- Упрощение интерфейса.
- Объединение нескольких интерфейсов в один.
- Сокращается количество объектов, участвующих во взаимодействии между системой и клиентом.
Однако, внутри фасада может скрываться много сложных и взаимосвязанных между собой компонентов, которые могут значительно затруднить проектирование и тестирование. Поэтому, при использовании паттерна Фасад необходимо учитывать его сложность и не злоупотреблять им.
Для создания паттерна Фасад в Python, обычно прибегают к созданию класса, который выполняет функцию фасада. Он содержит общедоступные методы, через которые клиенты могут общаться с системой, скрывая комплексность работы системы от клиента. Вот пример кода, демонстрирующий реализацию паттерна Фасад в Python:
ссылка на код (gist github Facade.py)
В данном примере мы создаем классы подсистем Subsystem1 и Subsystem2, а затем создаем класс фасада Facade, который использует методы подсистем для выполнения операции. Клиентский код вызывает методы фасада. Фасад скрывает сложность подсистемы от клиента.
5. Одиночка (Singleton)
Одиночка (Singleton) — это паттерн проектирования, который обеспечивает создание одного и только одного экземпляра класса, и предоставляет глобальную точку доступа к этому экземпляру.
Для реализации Одиночки необходимо скрыть конструктор класса и предоставить статический метод, который будет создавать (если он ещё не был создан) и возвращать единственный экземпляр класса.
Классический пример использования паттерна Одиночка - это логгеры. Каждый раз, когда приложение пишет лог, необходимо получать доступ к единственному экземпляру логгера.
Преимущества использования Одиночки:
- Гарантирует наличие единственного экземпляра класса
- Предоставляет глобальную точку доступа к этому экземпляру
- Позволяет создавать необходимое количество экземпляров, контролируя их количество и способ создания
Недостатки использования Одиночки:
- Затрудняет написание юнит-тестов
- Может привести к созданию глобальных переменных, что в свою очередь приводит к ухудшению модульности и увеличению связности между компонентами приложения.
В целом, паттерн Одиночка полезен в ситуациях, когда имеется необходимость в создании единственного экземпляра класса, который будет использоваться глобально в приложении.
ссылка на код (gist github Singleton.py)
Подытожим
Таким образом, можно заключить, что знание шаблонов программирования в Python является крайне полезным для разработчиков, позволяя им повышать эффективность и оптимизировать свой код. Мы рассмотрели 5 наиболее популярных шаблонов программирования в Python, которые могут пригодиться как начинающим, так и опытным разработчикам. Каждый из них имеет свои особенности и применение в определенных ситуациях.
А что касается вас, используете ли вы в своем опыте шаблоны проектирования? Поделитесь своими впечатлениями в комментариях к статье!