2.4. Множественные представления для абстрактных данных
179
декартова реализации могли быть написаны Беном и Лизой по отдельности, и любую
из них может использовать в качестве внутреннего представления третий программ ист,
чтобы реализовать процедуры арифметики комплексных чисел в терминах абстрактного
интерфейса конструкторов и селекторов.
Поскольку каждый объект данных помечен своим типом, селекторы работают с
дан ными обобщенным образом. Это означает, что каждый селектор по опреде лению о б-
ладает поведением, которое зависит от того, к какому типу данных он примен яется.
Следует обратить внимание на общий механизм доступа к отдельным представлени -
ям: внутри любой данной реализаци и представления (скажем, внутри полярного пакета
Лизы) комплексное число представляется нетипизированной парой (модуль, аргумент).
Когда обобщенн ый селектор обращается к данным полярного типа, он отрывает метку и
передает содержимое Лизиному коду. И наоборот, когда Лиза строит число для общего
пользования, она помечает его тип, чтобы процедуры более высокого уровня могли его
должным образом распознать. Такая дисциплина снятия и добавления меток при пере-
даче объектов данных с уровня на уровень может быть ценной стратегией организации
дан ных и программ, как мы у види м в разделе 2.5.
2.4.3. Программирование, управляемое данными, и аддитивность
Общая стратегия проверки типа данных и вызова соотве тствующей процедуры назы-
вается диспетчеризацией по типу (dispatching on type). Это хороший способ добиться
модульности при проектировании системы. С дру гой сторон ы, такая реализация диспет-
черизации, как в разделе 2.4.2, имеет два существенн ых недостатка. Один заключается
в том, что обобщенные процедуры интерфейса (real-part, imag-part, magnitude
и angle) обязаны знать про все имеющиеся способы представления. Предположим, к
примеру, что нам хочется ввести в нашу систему комплексных чисел еще одно пред-
ставление. Нам нужно будет сопоставить этому представлению тип, а затем добавить в
каждую из обобщенных процедур интерфейса по варианту для проверки на этот новый
тип и вызова селектора, соответствующего его представлени ю.
Второй недостаток этого метода диспетчеризации состоит в том, что, хотя отдельные
представлен ия могут проектироваться разде льно, нам нужно гарантировать, что никакие
две процедуры во всей системе не называются одинаково. Вот почему Бену и Лизе
пришлось изменить имена своих первоначальных процедур из раздела 2.4.1.
Оба э ти недостатка являются следствием того, что наш метод реализации обобщен-
ных интерфейсов неаддитивен. Программист, реализующий обобщенные процедуры-
селекторы, должен их переделывать каждый раз, как добавляется новое представле-
ние, а авторы, создающие отдельные представления, должны изменять свой код, чтобы
избежать конфликтов имен. В каждом из этих случаев изменения, которые требуется
внести в код, тривиальны, но их все равно нужно делать, и отсюда проистекают неудоб-
ства и ошибки. Для системы рабо ты с комплексными числами в ее нынешнем виде это
проблема небольшая, но попробуйте предс тавить, что есть не два, а сотни различных
представлен ий комплексных чисел. И что есть много обобщенных селекторов, которые
надо поддерживать в интерфейсе абстрактных данных. Представьте даже, что ни один
программист не знает всех интерфейсных процедур всех реализаций. Проблема эта ре-
альна, и с ней приходится разбираться в программах вроде систем управления базами
дан ных большого калибра.