типы данных и статическое связывание более эффективны, а динамические типы
данных и динамическое связывание более гибки.
Как мы видели, динамические типы данных подразумевают, что каждый объект
должен отслеживать свой собственный тип данных. Если мы посмотрим на
объекты с точки зрения «непреклонного индивидуалиста» (каждый объект должен
сам заботиться о себе и не зависеть от других), то динамические типы данных
кажутся более объектно-ориентированной методикой. Их применение сильно
упрощает, например, разработку структур данных общего назначения. Но не все
так просто — во время выполнения происходит постоянный поиск подходящего
кода. Хотя имеются способы уменьшения этих затрат, они не могут быть
устранены полностью. В основном именно потому, что такие накладные расходы
могут быть весьма значительными, большинство языков программирования
использует статические типы данных.
Статические типы данных упрощают реализацию языка, даже если (как в Java,
Object Pascal и иногда в C++) используется динамическое связывание метода с
сообщением. Когда компилятору известны статические типы данных, выделение
памяти под переменные происходит более эффективно, а для простых операций
(например, сложение чисел) генерируется почти совершенный код. Но имеются
затраты, связанные и со статическими типами данных. К примеру, часто объекты
могут терять знание о себе (хотя это не обязательно, как мы видели в случае языка
Object Pascal). Как мы отмечали при обсуждении проблемы контейнеров данных,
этот факт затрудняет написание абстракций структур данных общего назначения.
Если статические типы данных упрощают реализацию языка программирования, то
статическое связывание делает его почти элементарным. Если соответствие между
методом и сообщением может быть обнаружено компилятором, то пересылка
сообщений (независимо от используемого синтаксиса) представляется просто как
вызов процедуры: во время выполнения уже не требуется поиск подходящего
метода. Это, по-видимому, максимально эффективно (хотя механизм inline-
функций в C++ может устранить даже и код вызова процедуры).
Напротив, динамическое связывание всегда требует некоего run-time-механизма
(хотя бы и примитивного) для сопоставления метода и сообщения. В языках
программирования, которые используют динамические типы данных (и, как
следствие, динамическое связывание), вообще говоря, нельзя определить заранее,
будет ли пересылаемое сообщение восприниматься получателем. Когда сообщение
не распознается, то не остается другой альтернативы, кроме как сгенерировать
сообщение об ошибке этапа выполнения. Защитники статических языков
программирования настаивают, что большинство таких ошибок может быть
отловлено на этапе компиляции для языка со статическим связыванием методов.
Эта точка зрения оспаривается (как и следовало ожидать) сторонниками
динамического программирования.
Тем самым нам приходится решать, что более важно: эффективность или гибкость,
правильность или легкость использования. Брэд Кокс [Cox 1986] настаивает, что
решение зависит как от уровня абстракции программы, так и от того, являемся ли
мы производителями или потребителями программной системы. Кокс утверждает,
что объектно-ориентированное программирование будет основным (хотя и не
единственным) средством в «революции в области программной индустрии».
Точно так же как в девятнадцатом веке индустриальная революция стала возможна
PDF created with pdfFactory Pro trial version www.pdffactory.com