Соответствует ли образец в Scala принципу Open / Closed? - PullRequest
13 голосов
/ 19 февраля 2009

Если я добавлю новый класс case, означает ли это, что мне нужно найти весь код сопоставления с образцом и выяснить, где должен обрабатываться новый класс? Недавно я изучал язык, и когда я читал о некоторых аргументах за и против сопоставления с образцом, я не понял, где его следует использовать. Смотрите следующее:

Pro: Одерский1 и Odersky2

Con: Бойст

Комментарии довольно хороши и в каждом случае. Так что шаблон соответствует чему-то, что должно вызывать энтузиазм или что-то, чего я должен избегать? На самом деле, я думаю, что ответ «это зависит от того, когда вы его используете», но каковы некоторые положительные варианты использования и какие-то отрицательные?

Ответы [ 3 ]

22 голосов
/ 19 февраля 2009

Джефф, я думаю, у тебя правильная интуиция: это зависит.

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

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

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

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

16 голосов
/ 19 февраля 2009

Хотя я уважаю Седрика, он совершенно не прав в этом вопросе. При желании сопоставление с образцом в Scala может быть полностью заключено в изменения классов. Хотя верно, что для изменения класса дел потребуется изменить любые соответствующие экземпляры сопоставления с образцом, это только при использовании таких классов наивным способом.

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

Таким образом, мнению доктора Одерского здесь следует доверять, особенно с учетом огромного объема исследований, которые он провел в области объектно-ориентированного программирования и дизайна.

Что касается того, где его следует использовать, это полностью соответствует вкусу. Если это делает ваш код более кратким и понятным, используйте его! В противном случае нет. Для большинства объектно-ориентированных программ сопоставление с образцом не требуется. Однако, как только вы начнете интегрировать больше функциональных идиом (Option, List и т. Д.), Я думаю, вы обнаружите, что сопоставление с образцом значительно сократит синтаксические издержки, а также повысит безопасность, предлагаемую системой типов. Как правило, в любое время, когда вы хотите извлечь данные при одновременном тестировании некоторого условия (например, извлечение значения из Some), сопоставление с образцом, вероятно, будет полезным.

1 голос
/ 19 февраля 2009

Сопоставление с образцом определенно хорошо, если вы занимаетесь функциональным программированием. В случае ОО, есть несколько случаев, когда это хорошо. В примере самого Седрика это зависит от того, как вы видите концептуально метод print(). Это поведение каждого Term объекта? Или это что-то за пределами этого? Я бы сказал, что это снаружи, и имеет смысл сделать сопоставление с образцом. С другой стороны, если у вас есть класс Employee с различными подклассами, плохой выбор дизайна - сопоставление с шаблоном для его атрибута (скажем, имени) в базовом классе.

Также сопоставление с образцом предлагает элегантный способ распаковки членов класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...