Разница между идиомой и дизайном шаблона?

39

В чем разница между идиомой и дизайном? Кажется, что эти термины где-то частично совпадают; где именно, я не знаю. Они взаимозаменяемы? Когда я должен использовать что?

Вот список идиом C ++. Могу ли я назвать их шаблонами дизайна?

Википедия определяет,

Идиома программирования как шаблон проектирования низкого уровня

Что это означает? Что значит «низкий уровень» здесь?

Этот вопрос вдохновлен другим вопросом: https://stackoverflow.com/questions/7343531/are-the-some-design-patterns-language-dependent

Наваз
источник
С практической точки зрения различие может быть трудно определить (и может быть некоторый континуум между идиомой и образцом проектирования). Но это, вероятно, происходит от термина «идиома» на естественном языке: en.wikipedia.org/wiki/Idiom (который на самом деле не подходит для использования).
Мерлин Морган-Грэм,
2
Это, вероятно, лучше подходит для программистов SE.
Оливер Чарльзуорт,
3
@Nawaz: «Шаблон проектирования» - это относительно «высокоуровневая» конструкция вокруг языкового дефекта. «Идиома» - это относительно «низкоуровневая» конструкция вокруг языкового дефекта; )
Tristan St.
@ Наваз- +1 за юмор.
Дженнифер С.
Смотрите также Идиома против паттерна .
MS Dousti

Ответы:

30

Идиома - идея обойти причуды языка. Некоторые примеры, которые приходят на ум, - это любые идиомы C ++, которые вы связали в исходном вопросе. Они решают общую проблему на этом языке постоянным способом.

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

Тем не менее, существует неразрывная связь между идиомами и шаблонами проектирования, как и от языков низкого уровня до языков высокого уровня.

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

Также на ум приходит шаблон Observer - C # поддерживает его напрямую, поэтому ему не нужна общая обходная форма шаблона.

Примером, идущим в другом направлении, являются ОО-характеристики (наследование, полиморфизм и т. Д.). C не поддерживает их напрямую. Если бы больше языков было похоже на C, то мы могли бы разработать шаблоны проектирования для реализации v-таблиц, безопасности типов и т. Д. Поскольку многие языки поддерживают эту функцию, мы бы назвали любое общее решение в C идиомой, а не называли обобщенное Решение шаблон дизайна.

Мерлин Морган-Грэм
источник
2
Еще один интересный пример: свободные API синтаксиса. Они компенсируют тот факт, что у вас нет прямой поддержки DSL на вашем языке, и это выходит за границы языка. Я не уверен, что он перешел в статус «Шаблон проектирования», и он звучит как синтаксическая идиома ...
Мерлин Морган-Грэм,
Тот факт, что C # напрямую поддерживает шаблон Observer, может показаться, что он действительно нуждается в шаблоне настолько, что он переместил реализацию от разработчиков к самому языку.
jaco0646
@ jaco0646 Я перефразировал эту строку, может быть, теперь она будет более ясной
Мерлин Морган-Грэм,
37

Шаблоны проектирования обычно не зависят от языка. Языковые идиомы имеют тенденцию зависеть от конкретной особенности языка (или класса языков) или обходить определенный недостаток в указанных языках.

μBio
источник
+1 для проведения различия с несколькими словами и несколькими неточностями.
Мерлин Морган-Грэм,
1
@Merlyn Morgan-Graham: Вы прокомментировали почти все ответы, включая вопрос. Так почему бы вам не опубликовать подробный ответ без каких-либо неточностей вообще? Я хотел бы знать ваши мысли.
Наваз
1
@Nawaz: Комментарий был о других ответах. Этот уже почти идеален. В идеале я хотел бы, чтобы образцы были в ответе, но, похоже, никто не понимает их правильно. Я, вероятно, тоже не смог бы, иначе я бы с радостью пообещал :)
Мерлин Морган-Грэм,
@Nawaz: Ладно, я все равно попробовал :)
Мерлин Морган-Грэм,
12

Я бы не стал вкладывать слишком много денег в определение Википедии.

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

С другой стороны, шаблоны проектирования - это сущность повторяющейся идеи, идеи, которая априори может быть выражена на любых языках, которые ей подходят. Visitor - это реализация двойной отправки, основанная на однократной отправке и перегрузке, и она может использоваться на любом языке, который имеет однократную отправку и перегрузку. Знание шаблона не помогает писать более выразительный или более читаемый код, оно помогает решить связанную с этим проблему. В этом нет ничего идиоматического, потому что, например, в C ++ нет канонической формы Visitor.

Люк Дантон
источник
1
+1; Хороший ответ. Хотя я склонен верить всему здесь, кроме последнего. Существуют языки, которые имеют прямую поддержку множественной диспетчеризации, поэтому шаблон Visitor там не должен существовать. С их точки зрения, «шаблон» может быть скорее идиомой. На самом высоком языке все шаблоны могут стать идиомами ...
Мерлин Морган-Грэм,
@Merlyn Что идиоматично в реализации первоклассной языковой функции? Кто так делает?
Люк Дантон
В этом-то и дело. Пользователи этого языка будут считать «шаблон дизайна» идиомой, потому что их язык круче :)
Мерлин Морган-Грэм,
@Merlyn Это не подходит для моего использования «идиома». Идиома языка - это то, что вы ожидаете, что случайный, опытный пользователь языка узнает; Реализация первоклассной функции будет выглядеть чуждой и неуместной. Там нет идиома C ++ для одной отправки, просто используется virtualв некоторых местах, тогда как рукописный указатель на хитрость таблицы членов будет выглядеть просто глупо.
Люк Дантон
1
Мне нравится, когда вы идете с определением идиомы, отличной от «модели проектирования бедняков», которая как бы относится к моей модели (см. Мой ответ). Меньше «вот как это реализовать» и больше «вот правильный способ это реализовать». Например, я не могу представить, как «большая тройка» превращается в шаблон дизайна. И есть синтаксический компонент, например, do_something() or die "...";(украденный из другого комментария здесь). Он основан на определенных языковых возможностях, но это распространенный способ использования этих функций. Это не кросс-язык, и, вероятно, не будет.
Мерлин Морган-Грэм,
6

Нормальное английское определение языка идиома. Это фраза, общепринятое значение которой не содержится в используемых словах. Примерами могут быть «Дождь кошек и собак» или «Где говядина?»

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

Perl, пожалуй, самый богатый язык. С такими конструкциями, как:

while (<IN>) {
    print $_
}

Чей смысл очевиден для опытного программиста Perl, но загадка для всех остальных

Джеймс Андерсон
источник
Я думаю, «где говядина» - скорее мем, чем идиома. Там может быть другой континуум;) Идиома может быть чем-то большим, чем просто реализация в языке, поскольку вещи могут быть частичными или неудачными реализациями этой идиомы - например, «Большая тройка» C ++. В этом случае идиома - это название и описание «большой тройки».
Мерлин Морган-Грэм
2
У Perl лучшие идиомы -do_something() or die "arrrrgh!";
cxfx
2

Идиомы зависят от языка. Например while (*dest++=*src++);, это идиома C / C ++. Совершенно невозможно написать что-то похожее на Паскале или Java. Используйте слово "идиома", как вы используете его на английском языке. "Как дела?" как приветствие это идиома. Некоторые языки, такие как немецкий и французский, имеют одинаковую идиому. Но многие другие языки не будут «спрашивать» что-то вроде этого в качестве приветствия. Шаблон (объектно-ориентированный), с другой стороны, обычно может быть адаптирован к любому языку, который поддерживает наследование и делегирование. Идиома может быть такой же простой, как одна строка кода. Шаблон дизайна всегда включает в себя несколько классов.

Ангел О'Сфера
источник
+1. Хороший вопрос:A idiom might be as simple as one line of code. A design pattern always involves several classes.
Наваз
2

Я нашел этот пост в поиске распространенных идиом C ++, так как в последнее время я довольно глубоко углубился в него и хотел бы, чтобы мой код выглядел не так, как мне кажется, любительским ... :-P

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

Я не согласен с тем, что идиома похожа на «маленький шаблон дизайна». Я все еще не согласен, хотя и менее, что идиома - это способ обойти недостатки в языке.

Возможно , ответ Люка Дантона наиболее близок, но позвольте мне объяснить. Я думаю, что идиома, ну идиоматическая из тех, кто использует язык. Обычно это общее выражение или последовательность выражений, которые, хотя, возможно, и не очевидны, выполняют операцию или выражают намерение таким образом, который имеет смысл для тех, кто достаточно бегло , чтобы увидеть это раньше.

Возвращаясь к Perl, возможно, самая известная идиома - это « преобразование Шварца », выражение, которое выполняет сортировку данных компактным и эффективным способом. Это не самый очевидный способ выполнить такую ​​операцию, но она лаконична, и те, кто видел ее раньше, сразу же знают, что она делает.

Еще одним примечательным примером является « Маневр Орка », который использует в Perl представления об истинных / ложных, богатых операторах и приоритетах операторов.

Тот, который мне лично очень нравится, в некоторой степени связан с маневром орков, но я не знаю его названия:

push @{ $some_hash{$key} ||= [] }, $some_value;

Это действительно не запутывание, а скорее ясное, компактное выражение того, что в противном случае заняло бы несколько строк. Если ключ присутствует в хэше и имеет истинное значение, отмените ссылку на него как на массив и вставьте $ some_value в этот массив. Если элемент хеша отсутствует или имеет ложное значение, присвойте ему пустой массив, затем разыменуйте этот массив и выполните push.

Стоит также отметить, что в Perl 5.14 часть этой идиомы устарела - теперь push может работать непосредственно с ссылкой на массив, не нужно @ {}! Также, в Perl 5.10 можно использовать // = вместо || =, что проверяет не правду, а определенность.

Hercynium
источник
в Python: some_dict.setdefault(key, []).append(some_value).
Йонас Кёлкер
0

смысл идиомы заключается в том, чтобы быть идеей или концепцией, охватывающей языки программирования, это способ ведения дел и процесс, который работает без особой концептуальной реструктуризации, когда вы берете его из одного и втыкаете в другой, как смиренная сортировка , Шаблоны проектирования - это конкретные реализации идиомы или расширения идеи для встраивания в язык, поэтому у вас есть шаблон проектирования javascript идиомы слушателя событий и т. Д.


источник
слушатель событий - это языковая функция, которая реализует сигнал / слоты (шаблон?) или шаблон наблюдателя. В C ++ есть также вещи, называемые идиомами, которые просто не имеют значения или не вписываются в другие языки (насколько я знаю) - например, идиома копирования и замены.
Мерлин Морган-Грэм,
Design patterns are specific implementations of an idiom? Как именно? Вы видели идиомы C ++ в ссылке на мой вопрос?
Наваз
0

Я не уверен на 100%, но идиомы - это просто термины, относящиеся к определенной области. Когда вы говорите «шаблоны проектирования», вы подразумеваете «шаблон наблюдателя», «цепь ответственности», «шаблон посетителя», «фабрику». Это общие шаблоны, используемые для решения общих проблем в программировании. Смотрите здесь полный список: http://en.wikibooks.org/wiki/C++_Programming/Code/Design_Patterns


источник
0

Что это означает? Что значит «низкий уровень» здесь?

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

например, установка переменной, если она имеет значение false (обычно используется для условной установки переменных nil):

var ||= some_default_value
Эд С.
источник
0

Вот пример идиомы (в C #) для обработки события. Вы не можете запускать событие, если к нему не подключены какие-либо обработчики, поэтому идиома - всегда проверять это первым.

Поэтому общая идиома для обработки событий становится:

EventHandler handler = this.MyEvent;
if ( null != handler ) { handler( param1, param2 ); }

Эта идиома специфична (но не исключительна) для языка C #.

В более общем смысле, однако, механизм событий C # является примером шаблона проектирования наблюдателя, который может быть реализован на любом языке.

cxfx
источник