Решение упражнения 2.76 из SICP
Рассмотрим, что нам нужно сделать при добавлении нового типа или новой операции в систему с обобщенными операциями при разных стратегиях представления операций и типов.
1. Обобщенные операции с явной диспетчеризацией.При добавлении типа нам нужно будет:
- добавить специфичные операции типа по числу операций в системе;
- изменить все обобщенные операции, добавив в каждую условия проверки метки нового типа и вызова соответствующей операции нового типа.
При добавлении новой операции нам нужно будет:
- добавить для каждого типа специфичную реализацию этой операции;
- добавить обобщенную операцию в систему.
2. Стиль, управляемый данными.
При добавлении типа нам нужно будет:
- добавить пакет со всеми операциями реализованными для этого типа;
- добавить все реализации операций в таблицу типов с тегом этого типа.
Обобщенные операции при этом менять не нужно!
При добавлении новой операции нам нужно будет:
- изменить все пакеты типов, добавив для каждого типа специфичную реализацию этой операции и добавить эту реализацию в таблицу типов;
- добавить обобщенную операцию в систему.
3. Передача сообщений.
При добавлении типа нам нужно будет:
- добавить тип в виде конструктора с процедурой диспетчеризации, содержащей условия для каждой операции в системе;
Обобщенные операции при этом менять не нужно!
При добавлении новой операции нам нужно будет:
- изменить все конструкторы, добавив в каждый из них условие диспетчеризации для новой операции и ее реализацию для каждого типа;
- добавить обобщенную операцию в систему.
Какая же стратегия лучше при частом добавлении новых типов, а какая – при частом добавлении новых операций? В случае добавление нового типа меньше всего телодвижений приходится делать при передаче сообщений. В случае же добавления новой операции все не так однозначно. По большому счету, ни один из подходов не имеет большого преимущества перед другими.
Я был бы рад обсудить это упражнение. Мне кажется, что я тут мог упустить нечто важное. Комментарии приветствуются.
Comments
Comment from Андрей
Date: March 18, 2008, 5:08 pm
ИМХО вопрос должен стоять не в количестве телодвижений – они во всех случаях примерно одинаковые. Писать чуть меньше кода или чуть больше – это не так важно как то, где этот код писать/вставлять. Тогда очевидно, что при добавлении нового типа удобнее варианты с управлением данными и передачей сообщений, т.к. все изменения локализованы в пакетах/конструкторах типов. Когда добавляются новые операции удобнее пользоваться явной диспетчеризацией, т.к. тогда все изменения коснуться только новой операции и специфика для каждого типа может быть упрятана в нее.
Мне кажется задача намекает на инкапсуляцию. Вообще весь раздел 2.4 очень сильно перекликается с ООП. Скажем, примеры с таблицами процедур разбитыми по типам и операциям – это фактически прямой путь к реализации перегружаемых методов/операторов из C++/JAVA/подобные. Более того, они в реальности практически так и реализованы. Передача сообщений – очень близка к ООП а-ля Smalltalk. Вообще конечно забавно как меняется представление о других языках при прочтении сикп и необходимости существования специальных синтаксических конструкций для реализации тех или иных парадигм.
Comment from Dima
Date: September 2, 2008, 2:20 am
В “Стиль, управляемый данными”, при добавлении новой операции не обязательно изменять пакеты типов. Можно сделать новый пакет с одной операцией для всех типов. Тогда менять вообще ничего не надо.
Write a comment