Существуют ли какие-либо шаблоны проектирования, которые не нужны в динамических языках, таких как Python?


98

Я начал читать книгу шаблонов дизайна от GoF. Некоторые модели кажутся очень похожими с незначительными концептуальными различиями.

Считаете ли вы, что из многих шаблонов некоторые не нужны в динамическом языке, таком как Python (например, потому что они заменены динамическим признаком)?


1
Вроде интересный вопрос, поскольку он подразумевает, что выбор языка может эффективно заменить конструкции кода.
joshin4colours

3
Не ответ, но уместно - я думал, что шаблоны проектирования GoF столь же актуальны для некоторых общих принципов, которые можно извлечь из них, так и для конкретных шаблонов. Я не имею в виду идею шаблона (хотя это, безусловно, важно), а скорее разрешение использовать классы определенными способами, которые нарушают наивные принципы ООП. Например, существует множество шаблонов, в которых «форма» совершенно явно не «рисует сама» или, по крайней мере, делегирует какой-то аспект задания другому объекту. Я думаю, что урок важен на любом языке, который поддерживает ООП.
Steve314

Очень интересный вопрос Я бы хотел +5 вместо +1.
Математическая атака

1
Посмотрите также на Шаблоны проектирования, в которых отсутствуют функции языка, а шаблоны проектирования отсутствуют в функциях языка в c2. Это даже не проблема «динамического языка». Простейшим примером является шаблон итератора, который тривиален в Python, Perl (и даже Java - не динамический).

Ответы:


92

Питер Норвиг показывает, что 16 из 23 шаблонов проектирования, описанных в книге GOF, невидимы или проще в динамических языках (он фокусируется на Лиспе и Дилане).

Поскольку вы упомянули Python, у Алекса Мартелли есть хорошая презентация на эту тему. Также, в связи с Python, есть хороший пост в блоге, демонстрирующий шесть шаблонов дизайна в идиоматическом Python .

Я также держу github-репозиторий с реализациями (другими людьми) наиболее распространенных шаблонов проектирования в Python .


Большой! Это было бы место для ответа :) Я хотел бы, чтобы все поняли вопрос так ясно.
Геренюк

2
Согласно Норвигу, 2 из 16 (Интерпретатор и Итератор) «либо невидимы, либо проще» из-за макросов (которых нет в Python).
MJS

1
мне не ясно, что все эти шаблоны не нужны, потому что lisp динамичен, а скорее из-за других функций, таких как сильный функциональный язык
jk.

@mjs Итераторы - это встроенная функция Python.
Сакиск

1
Этот замечательный ответ можно даже немного улучшить, изменив несколько бессмысленные ссылки на заголовки, демонстрацию , презентацию и репозиторий - они намного лучше, чем здесь , но, вы знаете ... :-)
Wolf

59

Никаких шаблонов проектирования не требуется. На любом языке.

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

Шаблоны проектирования существуют для того, чтобы у вас был набор полезных идиом, пригодных для решения проблем. Но вы никогда не должны применять какой-либо шаблон, прежде чем выявить проблему. Keep It Simple Stupid всегда должен быть главным руководящим принципом.

Это также помогает думать о шаблонах проектирования как о концепции, позволяющей думать о проблеме, а не о конкретном шаблонном коде, который нужно написать. И о большей части стандартного обходного пути в качестве обходного пути к Java не хватает свободных функций и стандартных функциональных объектов, которые вы используете в большинстве других языков, в которых они есть (например, Python, C #, C ++ и т. Д.).

Я мог бы сказать, что у меня есть шаблон посетителя, но на любом языке с функциями первого класса это будет просто функция, принимающая функцию. Вместо фабричного класса у меня обычно есть только фабричная функция. Я мог бы сказать, что у меня есть интерфейс, но тогда это всего лишь пара методов, помеченных комментариями, потому что не было бы никакой другой реализации (конечно, в python интерфейс всегда является просто комментариями, потому что он имеет утку). Я до сих пор говорю о коде как об использовании шаблона, потому что это полезный способ думать об этом, но на самом деле не набирайте весь материал, пока он мне действительно не понадобится.

Итак, изучите все шаблоны как концепции . И забудьте о конкретных реализациях. Реализация меняется и должна меняться в реальном мире, даже в Java.


28
Ваше вступительное заявление упрощает до крайности. Это правда, что шаблоны имеют свою стоимость, поэтому их не следует использовать вслепую, просто ради этого. Но в нужном месте они могут оказать большую помощь. И да, они зависят от языка - некоторые шаблоны не нужны в некоторых языках, потому что сам язык поддерживает лучший подход. Но это все еще довольно далеко от вашего первого заявления.
Петер Тёрёк

2
Кстати, Visitor не полностью заменен функциями более высокого порядка - это решение для реализации двойной диспетчеризации на языке, который не поддерживает его изначально (например, C # и C ++). (И это действительно должно использоваться очень экономно - я считаю это одним из самых загадочных и дорогостоящих паттернов, использование которых ИМХО настолько трудно оправдать, что я сам никогда не использовал его до сих пор.)
Péter Török

14
Ну, тебе никогда не нужен шаблон. Что вам нужно, это решить проблему . Если вы не знаете какой-либо шаблон для него, вы все равно можете решить его, это потребует больше размышлений, и вы можете найти решение, которое соответствует некоторому шаблону или шаблону, который этого не делает. Знание шаблонов просто делает это проще.
Ян Худек

3
@ Геренюк: Да, но дело в том, что шаблоны не зависят от языка, они для вашей головы. Вы часто обнаруживаете, что какой-то шаблон реализуется гораздо проще и использует разные инструменты в Python, но обычно существует одна и та же концепция.
Ян Худек

4
@ PéterTörök: посетитель не заменяется ничем. Дело в том, что одна и та же концепция может быть реализована с использованием разных инструментов в разных случаях, но я все же считаю, что это один и тот же шаблон.
Ян Худек

13

Абстрактный фабричный шаблон не нужен в языке утки, таком как Python, так как он практически встроен в язык.


10
ну, вам все еще нужны разные фабрики. Вам просто не нужно определение интерфейса.
Стефано Борини

1
Если у вас есть класс, у вас уже есть фабрика. Классы являются объектами первого класса и могут передаваться везде и просто вызываться для создания объекта (в отличие от Java). Вам не нужно ничего создавать. Если вы хотите что-то, что не является конструктором по умолчанию, просто создайте лямбда-функцию, которая может каким-то образом обернуть конструктор.
spookylukey

13

Единственное, что приходит на ум - это модель Синглтона.

Поскольку Python не заставляет вас использовать классы для всего , вместо этого вы можете просто использовать глобальную структуру данных. Эта глобальная структура данных может управляться экземпляром, но вам не нужно управлять созданием этого класса, вы просто создаете экземпляр при импорте и оставляете все как есть.

В основном синглтоны в python заменены модулем. Модули в python по своей природе являются синглетонами; интерпретатор Python создает их только один раз.

Все другие шаблоны в Design Patters я использовал в Python то или иное время, и вы найдете их примеры во всей стандартной библиотеке Python и в самом Python.


2
Разве это не анти-паттерн в наши дни?
Ден

16
Синглтон - это антипаттерн . На всех языках. Он был создан для решения нескольких несвязанных проблем и не подходит ни для одного из них (обратите внимание, что даже в Java есть статические члены, которые существуют один раз для каждого класса, поэтому вам не нужен экземпляр для этого).
Ян Худек

1
И в Python мы никогда не беспокоились об этом, так как никогда не было проблемы, которую нужно решить.
Мартин Питерс

1
«Python не заставляет вас использовать объекты для всего» Не верно. Это просто не противно, как в Java, но все же в Python все является объектом. Даже модуль - это объект.
vartec

3
@Darthfett: я хорошо знаю, как lenработает; Гвидо сделал здесь явный выбор . Я хочу показать, что Python не является чистым языком ООП; это прагматичный язык. Мне так нравится.
Мартин Питерс

8

Шаблоны проектирования предназначены для программиста, а не для языка. Программисты склонны использовать шаблоны, которые помогают им разобраться в проблеме. Никакой шаблон дизайна не является строго необходимым, но он может быть полезен, чтобы упростить то, что вы пытаетесь сделать.

Python, и, в частности, типизация утиным шрифтом, обеспечивает конец многим распространенным шаблонам и практикам, и многие ограничения, накладываемые некоторыми шаблонами (конфиденциальность, неизменность и т. Д.), Сохраняются только в той степени, в которой программист соглашается не нарушать их. , Но все - таки, они действительно работают до тех пор , как программист подыгрывает. Дверь остается дверью, даже если она обрамлена воображаемыми стенами.

Python считается «мультипарадигмальным» языком; Вы можете использовать любые шаблоны, которые вы хотите. Это намеренно. Например, он предусматривает сложные иерархии классов, даже если они совершенно не нужны и немного искусственны. Но для некоторых людей эта конкретная абстракция полезна. Не потому, что проблема требует этого, а потому, что программист делает. Итак, поехали.


Это конечно интересно. Итак, какие именно шаблоны вы имеете в виду, о которых можно забыть, потому что в Python есть лучшие способы?
Геренюк

4

Оригинальная книга «Шаблоны проектирования» документирована и названа некоторыми общими идиомами, полезными в императивных объектно-ориентированных языках, таких как C ++ и Smalltalk. Но Smalltalk - это язык с динамической типизацией, поэтому он не может быть просто вопросом динамичности.

Тем не менее, ответ на ваш вопрос по-прежнему «да»: некоторые из этих шаблонов проектирования не будут иметь отношения к современным динамически типизированным языкам. В более общем плане , будут различными шаблоны проектирования на разных языках, особенно в различных видах языков.

Повторим еще раз: «шаблон проектирования» - это просто название идиомы программирования: общее решение часто встречающейся проблемы. Разные языки требуют разных идиом, потому что проблема для одного языка может быть тривиальной для другого. В этом смысле шаблоны проектирования, как правило, указывают на слабые места в языках, к которым они применяются.

Таким образом, вы можете искать другие функции, которые делают современные динамические языки (или древние, такие как Lisp) более мощными, что делает некоторые из этих классических шаблонов проектирования неактуальными.


1

Шаблоны проектирования - это способы решения конкретных проблем. Если проблема не встречается, шаблон ее решения не имеет смысла.

Люди пытаются адаптировать шаблоны проектирования везде, как если бы это было наилучшей практикой - использовать шаблоны проектирования в вашем проекте. Это наоборот. Вы сталкиваетесь с проблемой, которую можно решить с помощью заводской схемы? Здорово. Адаптируй это. Не ищите свой код и не пытайтесь найти подходящее место для реализации синглтона (или фабрики, или фасада, или чего-то еще ...).

Возможно, у Python есть свои собственные шаблоны проектирования, недоступные для людей на Java и .NET (из-за природы этих языков)?


1

Я бы сказал, что шаблоны всегда зависят от языка. Большинство шаблонов python выглядят так же, как те, которые определены в GoF, потому что ООП Python говорит о том, что ООП не похож на ООП (никакие два языка не определяют объекты и их манипуляции на 100% одинаковые).

Поэтому нет сомнений, что некоторые шаблоны не будут применимы «как есть», некоторые могут не иметь смысла, и есть некоторые шаблоны, которые могут иметь смысл только для Python.

Чтобы точно ответить на ваш вопрос: шаблоны необходимы только в том случае, если они вам нужны . Вам не нужно их использовать, если в них нет необходимости (как уже сказал Ян Худек).

Кроме того, шаблонов гораздо больше, чем в GoF. Смотрите в википедии другие шаблоны

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.