Шаблоны проектирования в Python
Оригинальная статья: Darinka Zobenica — Design Patterns in Python
Введение
Шаблоны проектирования — это многократно используемые модели для решения известных и распространенных проблем в архитектуре программного обеспечения.
Их лучше всего описать как шаблоны для работы с определенной ситуацией. У архитектора может быть шаблон для проектирования определенных видов дверных коробок, который он вписывает во многие свои проекты, а разработчик программного обеспечения или архитектор программного обеспечения должен знать шаблоны для решения частых задач программирования.
Хорошее представление шаблона дизайна должно включать:
- Имя
- Мотивирующая проблема
- Решение
- Выводы
Эквивалентные проблемы
Если бы вы думаете, что это довольно нечеткая концепция, вы будете правы. Например, мы могли бы сказать, что следующий «шаблон» решает все ваши проблемы:
- Получить и подготовить необходимые данные и дополнительные ресурсы
- Сделать необходимые расчеты и выполнить необходимые работы
- Сделать записи о том, что мы делаем
- Освободить все ресурсы
- ???
- Результат
Это пример слишком абстрактного мышления. Такой подход нельзя назвать шаблоном, потому что это не очень хорошая модель для решения любой проблемы, несмотря на то, что она технически применима к любой из них (включая приготовление обеда).
С другой стороны, у могут быть решения, которые слишком конкретны, чтобы так же называться шаблоном. Например, можно задаться вопросом, является ли QuickSort шаблоном для решения проблемы сортировки.
Это, безусловно, распространенная проблема программирования, и QuickSort является хорошим решением для нее. Тем не менее, это может быть применено к любой проблеме сортировки практически без изменений.
Как только вы поместите этот алгоритм в библиотеку и сможете вызвать его, вашей единственной реальной задачей будет — решить как сделать ваши данные сопоставимыми алгоритму. Вам не нужно самостоятельно разбираться с его сущностью, чтобы модифицировать его в соответствии с вашей конкретной проблемой.
Эквивалентные проблемы находятся где-то между этими понятиями. Это разные проблемы, которые достаточно похожи, и вы можете применить к ним одну и ту же модель решения, но при этом и достаточно разные, чтобы эту модель нужно было значительно адаптировать, для того чтобы ее можно было бы применить в каждом конкретном случае.
Шаблоны, которые могут быть применены к такого рода проблемам, — это то, что мы можем называть шаблонами проектирования.
Зачем использовать шаблоны проектирования?
Вы, вероятно, знакомы с некоторыми шаблонами проектирования уже по практике написания кода. Многие хорошие программисты в конце концов тяготеют к ним, даже если их не учат явно, или просто подбирают их у старших на своем пути.
Мотивации для создания, изучения и использования шаблонов проектирования разнообразны. Это способ дать имена сложным абстрактным понятиям, чтобы обеспечить обсуждение и обучение. Они ускоряют общение внутри команд, потому что кто-то может просто использовать имя шаблона вместо того, чтобы долго описывать проблему. Они позволяют учиться на опыте людей, которые были до вас, вместо того, чтобы заново изобретать колесо, пройдя через весь путь постепенного улучшения практики самостоятельно.
Плохие решения, которые обычно применяются, потому что на первый взгляд кажутся логичными, часто называют анти-паттернами. Чтобы что-то справедливо называлось анти-паттерном, его необходимо заново изобрести, и для этой же проблемы должен быть «правильный» паттерн, который решает проблему лучшим образом.
Несмотря на очевидную полезность на практике, шаблоны проектирования также полезны для обучения. Они знакомят вас со многими проблемами, которые вы, возможно, не рассматривали, и позволяют задуматься о сценариях, в которых вы, возможно, не имели практического опыта углубленного изучения.
Шаблоны проектирования в Python
Традиционно шаблоны проектирования разделены на три основные категории: порождающие, структурные и поведенческие. Существуют и другие категории, такие как архитектурные (architectural) или параллельные (concurrency) шаблоны, но они выходят за рамки этой статьи.
Существуют также специфичные для Python шаблоны проектирования, которые созданы специально для решения проблем, которые создаются структурой самого языка, или для решения проблем особым образом, которые допускаются только в этой структуре языка.
Порождающие шаблоны имеют дело с созданием классов или объектов. Они служат для абстрагирования от специфики классов, чтобы мы были менее зависимы от их точной реализации, или чтобы нам не приходилось иметь дело со сложной конструкцией всякий раз, когда они нам нужны, или чтобы мы обеспечивали некоторые специальные свойства создания экземпляров. Они очень полезны для понижения уровней зависимости и контроля того, как пользователь взаимодействует с нашими классами.
Структурные шаблоны проектирования объединяют объекты и классы в более крупные структуры, сохраняя при этом гибкость и эффективность этих структур. Они имеют тенденцию быть действительно полезными для улучшения читабельности и удобства сопровождения кода, обеспечения правильного разделения, инкапсуляции функций и наличия эффективных минимальных интерфейсов между взаимозависимыми объектами.
Поведенческие шаблоны проектирования имеют дело с алгоритмами в целом и распределением ответственности между взаимодействующими объектами. Например, это хорошая практика в тех случаях, когда у вас может возникнуть искушение реализовать простое решение, например, busy waiting или загрузить ваши классы ненужным кодом для одной конкретной цели, которая не является ядром их функциональности.
Порождающие шаблоны
Струтктурные шаблоны
Coming soon!
- Adapter
- Bridge
- Composite
- Decorator
- Facade
- Flyweight
- Proxy
Поведенческие шаблоны
Coming soon!
- Chain of Responsibility
- Command
- Iterator
- Mediator
- Memento
- Observer
- State
- Strategy
- Visitor
Шаблоны специфичные для Python
Coming soon!
- Global Object Pattern
- Prebound Method Pattern
- Sentinel Object Pattern