#cpp #delphi #ооп
В чем разница между шаблонами, паттернами и дженериками? Являются ли все три понятия одинаковыми по смыслу и разница в переводе? Или разница заключается в том как реализуются в разных языках одинаковый по смыслу функционал типа List? В частности вопрос возник во время прочтения сравнений языков программирования и частого тезиса "В C++ есть шаблоны и нигде больше таких нет"
Ответы
Ответ 1
Шаблоны (templates) в Си++ это частный случай обобщённых типов (generic types). Обобщённые типы в Си++ очень мощные, Тьюринг-полные. Вы, например, можете вычислять числа Фибоначчи во время компиляции с помощью шаблонов Си++. В других языках (Java, C#) обобщённые типы гораздо проще. Соответственно, проще и компилятор, и отлов странных труднопонимаемых ошибок (см. Александреску головного мозга). Обобщённые типы — довольно старая концепция, придуманная в одной из первых реализаций ML. Она позволяет избежать дублирования кода, не зависящего от конкретного типа, либо накладывающего на тип не очень строгие ограничения. Например, обобщённый алгоритм, считающий среднее арифметическое коллекции объектов, накладывает на тип элементов два ограничения: элемент можно сложить с элементом и элемент можно разделить на целое число (такой тип ограничений реализован далеко не во всех языках программирования). Обобщённая структура данных "список" не накладывает на тип элементов никаких ограничений, кроме тех, которые и так присущи любым объектам. В старых версиях таких языков, как C++, Java, C# без поддержки обобщённых типов, приходилось писать отдельную реализацию списка для каждой иерархии, либо постоянно приводить типы вверх и вниз. Что касается паттернов (patterns) то обычно под ними понимают крупные единицы проектирования объектно-ориентированных программ. Например, такие решения доступа к базам данных, как repository, unit of work, active record являются паттернами (они, описаны, в частности, в книгах Фаулера). DDD описывает паттерны aggregate root и value-object, Dependency Injection реализуется с помощью паттернов composite root, constructor injection и т.д. Есть так же главная книга по паттернам, которая называется — Паттерны объектно-ориентированного проектирования.Ответ 2
Каждая область информационных технологий или язык программирования имеет свои термины, семантика которых определяются в соответствующих нормативных документах, как, например, в соответствующих стандартах. Например, в языке программирования C++ используется термин шаблоны - templates. В языках программирования таких, как, например, C# или Eiffel используется термин дженерикс - generics. Точное их определение и поведение зависит от того, в каком языке программирования или технологии они используются. Значение термина паттерн также зависит от технологии или контекста, где он используется. Например, существуют паттерны проектирования задач, или паттерны поиска подстроки в строке и т.д. Если вы говорите в контексте какой-нибудь технологии или языка программирования, то следует использовать термины правильно, как они определены в той или иной технологии или языке программирования. С другой стороны, эти же термины могут использоваться в более широком смысле независимо от конкретной технологии или языка программирования. То есть эти термины могут использоваться как в узком специализированном значении, определяемом в соответствии с конкретной технологией или языком программирования, так и в более широком значении, определяемом из контекста. Что касается вашего примера со списком, то тут больше подходят термины интерфейс и реализация. И первое, и второе могут различаться от описания к описанию, или от проекта к проекту. Есть некоторые общие концепции, которые позволяют классифицировать списки, как, например, односвязные списки, двусвязные списки, кольцевые списки и т.д. Даже для одного и того же класса списков может быть определен разный интерфейс и разная реализация. Например, в стандартном односвязном списке в C++ std::forward_list отсутствует такое свойство списка, как количество элементов в списке. В других языках программирования односвязный список может не иметь те свойства, которые определены для односвязного списка в C++. К тому же списки могут быть реализованы как шаблонные или дженерикс списки. Как видите, здесь все опять упирается в точное определение и более обобщенные определения, зависящие от контекста.Ответ 3
Эти понятия имеют кучу разных смыслов. Пожалуй, генерики наиболее однозначная штука - это именно то, что описывается в сравнении генериков в C# с шаблонами C++. Это просто возможность применить алгоритм к чему-то в обобщённом виде. Шаблон может означать template или pattern. В случае template это могут быть шаблоны Си++ или просто некий макет чего угодно. Т. е. это то, куда можно что-то подставить и получить конкретную реализацию именно для подставленных значений. Паттерны - это pattern, но смыслов всё равно несколько. Паттерны проектирования (или шаблоны проектирования) - это высокоуровневые способы реализации взаимодействия между компонентами. Не совсем верно, но общий смысл отражает. За более подробным можно заглянуть в википедию. Паттерн может обозначать образец чего либо. Pattern matching - сопоставление с образцом. Многие языки вводят декомпозицию объекта или проверку на соответствие таким образом. Например, в ES6 вводится возможность декомпозиции объекта таким образом: var {x, y:z} = obj; - теперь объявлены две переменные x и z, причём выполнено присваивание x=obj.x, y=obj.z. Распространённый пример - обмен значений местами в питоне. Рассматривается добавление в C#. По сути, все эти понятия (помимо паттернов проектирования, которые являются ещё более высокоуровневыми) относятся к метапрограммированию, которое очень стараются добавлять в современные языки.
Комментариев нет:
Отправить комментарий