![]() |
|||
|---|---|---|---|
Критерии объектной ориентации О критериях
Все это не меняет очевидного: для обоснованного выбора, даже если практические ограничения навязывают далеко не совершенные решения, необходимо видеть полную картину.
Такое деление удобно, но не абсолютно, поскольку некоторые критерии относятся к двум или трем категориям. Например критерий, помеченный "управление памятью", относится к категории языка, поскольку язык может поддерживать или не допускать автоматическую сборку мусора. Этот же критерий относится к категории реализации и среды.
ОО-язык и ОО-среда, вместе с поддерживающим их методом, должны быть применимы ко всему жизненному циклу, минимизируя сложность переходов между последовательными шагами.
|
|||
Как уже отмечалось, "сущность" - это имя, к которому во время выполнения могут присоединяться различные значения. Сущность - это обобщение традиционного понятия переменной. |
Полиморфизм (polymorphism) - способность присоединять к сущности объекты различных возможных типов. В статически типизированной среде полиморфизм не будет произвольным, а будет контролироваться наследованием.
Должна иметься возможность в период выполнения присоединять к сущности объекты различных возможных типов под управлением наследования.
Динамическое связывание
Сочетание последних двух механизмов, переопределения и полиморфизма, непосредственно предполагает следующий механизм. Допустим, есть вызов, целью которого является полиморфная сущность, например сущность типа BOAT вызывает компонент turn. Различные потомки класса BOAT, возможно, переопределили этот компонент различными способами. Ясно, что должен существовать автоматический механизм, гарантирующий, что версия turn всегда соответствует фактическому типу объекта, вне зависимости от того, как объявлена сущность. Эта возможность называется динамическим связыванием (dynamic binding).
Вызов сущностью компонента всегда должен запускать тот компонент, который соответствует типу присоединенного объекта, а не типу сущности.
При различных выполнениях одного и того же вызова могут запускаться разные компоненты.
Динамическое связывание оказывает большое влияние на структуру ОО-приложения, поскольку дает возможность разработчикам писать простые вызовы, например объект my_boat вызывает компонент turn. В действительности, данный вызов означает несколько возможных вызовов, зависящих от соответствующих ситуаций времени выполнения. Это упраздняет необходимость многих повторных проверок (является ли объект merchant_ship? Является ли он sports_boat?), наводняющих программные продукты, создаваемые при обычных подходах.
Разработчики ОО-ПО вскоре вырабатывают здоровую неприязнь к любому стилю вычислений, основанному на явном выборе между различными типами объекта. Полиморфизм и динамическое связывание намного предпочтительнее. Однако в некоторых случаях объект приходит извне, так что автор ПО не имеет возможности с определенностью предсказать его тип. В частности, это случается, если объект извлекается из внешних хранилищ, получен по сети или передан некоторой другой системой.
Тогда ПО нуждается в механизме, обеспечивающем безопасный способ доступа к объекту без нарушения ограничений статической типизации. Такой механизм должен проектироваться с большой аккуратностью, так чтобы не утратить пользы от полиморфизма и динамического связывания.
Операция попытка присваивания (assignment attempt) удовлетворяет этим требованиям. Это условная операция: она пытается присоединить объект к сущности; если при выполнении операции тип объекта соответствует типу сущности, то она действует как нормальное присваивание; в противном случае сущность получает специальное значение void. Итак, можно управлять объектами, тип которых не известен наверняка, не нарушая безопасности системы типов.
Необходимо иметь возможность определять во время выполнения, соответствует ли тип объекта статически заданному типу.
Отложенные (deferred) свойства и классы
В некоторых случаях, для которых динамическое связывание дает элегантное решение, устраняя необходимость явных проверок, не существует начальной версии компонента, подлежащего переопределению. Например, класс BOAT может быть настолько общим, что не может обеспечить реализацию turn по умолчанию. Все же, мы хотим иметь возможность вызвать компонент turn сущностью типа BOAT, если мы уверены, что во время выполнения она будет получать значение объектов таких полностью определенных типов как, например, MERCHANT_SHIP и SPORTS_BOAT.
В таких случаях BOAT может объявляться как отложенный класс (класс, который не полностью реализован) и с отложенной реализацией компонента turn. Отложенные свойства и классы все же могут иметь утверждения, описывающие их абстрактные возможности, но их реализация откладывается для классов потомков. Если класс не является отложенным, - он считается эффективным.
Необходимо иметь возможность написания класса или компонента как отложенного, то есть специфицированного, но не полностью реализованного.
Отложенные классы (также называемые абстрактными классами) особенно важны для ОО-анализа и высокоуровневого проектирования, поскольку они делают возможным задать основные аспекты системы, оставляя детали до более поздней стадии.
Управление памятью (memory management) и сборка мусора (garbage collection)
Может показаться, что этот критерий метода и языка должен принадлежать к следующей категории - реализации и среде. На самом деле он принадлежит к обеим категориям. Важнейшие требования предъявляются к языку, остальное - это вопрос хорошей инженерии.
ОО-системы даже в большей степени, чем традиционные системы, за исключением, быть может, Lisp, имеют тенденцию создания большого числа объектов, иногда со сложными взаимозависимостями. Политика, возлагающая на разработчиков ответственность за управление памятью, вредит и эффективности процесса разработки, и безопасности полученной системы. Трудно утилизировать память, занятую более не нужными объектами, усложняются программы, все это требует времени разработчиков, увеличивается риск некорректной обработки областей памяти. В хорошей ОО-среде управление памятью будет автоматическим, под контролем сборщика мусора (garbage collector) - компонента системы периода выполнения (runtime system).
Автоматическая сборка мусора - это проблема языка, так же как и реализации. Если язык явно не спроектирован для автоматического управления памятью, то зачастую реализация становится невозможной. Это справедливо для языков, где, например, указатель на объект определенного типа может быть преобразован (используя кастинг - cast) в указатель другого типа или даже в целое число, - такие средства делают невозможным создание надежного сборщика мусора.
Язык должен давать возможность надежного автоматического управления памятью, а реализация должна обеспечить наличие автоматического менеджера, управляющего памятью, в функцию которого входит сборка мусора.
Мы подошли к важным свойствам среды разработки, поддерживающей создание ОО-ПО.
Автоматическое обновление (automatic update)
Разработка ПО - процесс нарастающий. Разработчики обычно не пишут тысячи строк за один раз; они работают, добавляя и модифицируя, начиная чаще всего с системы, уже имеющей значительный размер.
При выполнении такого обновления важно иметь гарантию, что полученная в результате система будет согласованной. Например, если вы меняете некоторый компонент f класса C, то вы должны быть уверены, что любой потомок C, который не переопределяет f, получит новую версию f, и что каждое обращение к f клиента C или потомка C будет запускать эту новую версию.
Традиционные подходы к этой проблеме предполагают работу вручную, заставляя разработчиков записывать все зависимости и прослеживать их изменения, используя специальные механизмы, известные как "создавать файлы" и "включать файлы". Это неприемлемо в современных разработках программных продуктов, особенно в ОО-мире, где взаимозависимости между классами, вытекающие из отношений наследования, часто сложны, но могут быть выведены из систематического рассмотрения текста ПО.
Обновление системы после изменения должно быть автоматическим, а анализ межклассовых зависимостей выполняться инструментарием, а не вручную разработчиками.
Это требование можно удовлетворить в компилируемой среде (где компилятор будет работать вместе с инструментарием, выполняющим анализ зависимостей), в интерпретируемой среде или в среде, сочетающей обе эти техники реализации языка.
Быстрое обновление (fast update)
На практике механизм обновления системы должен быть не только автоматическим, но и быстрым. Более точно, он должен быть пропорциональным размеру изменений, а не размеру системы в целом. Без этого свойства метод и среда могут быть применимыми только к небольшим системам, а применять их нужно к большим.
Время обработки ряда изменений в системе, создающих обновленную версию, должно быть функцией размера измененных компонентов и не зависит от размера системы в целом.
И компилируемая, и интерпретируемая среда могут удовлетворять этому критерию, хотя в последнем случае компилятор должен быть инкрементным (он не должен все компилировать заново). Наряду с инкрементным компилятором, среда может, конечно, включать глобальный оптимизирующий компилятор, работающий на всей системе. При условии, что глобальный компилятор нужен только для выпуска конечного продукта, разработка будет в основном использовать инкрементный компилятор.
Живучесть (persistence)
Многие приложения, вероятно, большинство, требуют сохранения объектов от одного сеанса до следующего. Среда должна обеспечивать механизм выполнения этого простым способом.
Объект часто содержит ссылки на другие объекты, тоже содержащие, в свою очередь, ссылки на объекты. Поэтому каждый объект может иметь большое количество зависимых объектов с возможно сложным графом зависимости (который может содержать циклы). Обычно не имеет смысла сохранять или восстанавливать объект без всех его прямых и непрямых зависимых объектов. Говорят, что механизм живучести поддерживает замыкание живучести (persistence closure), если он может автоматически сохранять зависимые объекты наряду с самим объектом.
Должен существовать механизм хранения, поддерживающий замыкание живучести. Он сохраняет объект вместе со всеми зависимыми объектами на внешних устройствах и восстанавливает их в течение того же или другого сеанса.
Для некоторых приложений простой поддержки живучести недостаточно; такие приложения нуждаются в полной поддержке баз данных (database support) . Понятие ОО-базы данных объясняется в одной из дальнейших лекций, где также исследуются другие вопросы живучести, такие как эволюция схемы, способность безопасного восстановления объектов, даже если изменились соответствующие классы.
Документация
Разработчики классов и систем должны обеспечивать руководство, заказчиков и других разработчиков ясными высокоуровневыми описаниями создаваемого ПО. Им необходим инструментарий, помогающий в этой работе. Большая часть документации должна автоматически создаваться на основе текстов ПО. Утверждения, как уже отмечено, помогают сделать такие документы, извлекаемые из ПО, точными и информативными.
Должны быть в наличии инструментальные средства для автоматического получения документации о классах и системах.
Быстрый просмотр (browsing)
При работе с классом часто необходимо получить информацию о других классах; в частности, компоненты данного класса часто могут определяться не в самом классе, а в его различных предках. Среда должна обеспечить разработчиков инструментами для исследования текста класса, нахождения зависимых классов и быстрого переключения с текста одного класса на другой.
В этом и состоит задача просмотра. Типичные хорошие возможности просмотра включают: поиск классов - клиентов, поставщиков, потомков, предков; поиск всех переопределений компонента; поиск исходного объявления переопределенного компонента. (Определение: S - поставщик С, если С - клиент S. Термин "клиент класса" пояснен выше.)
Средства интерактивного просмотра должны давать возможность разработчикам ПО быстро и удобно прослеживать зависимости между классами и компонентами.
Один из характерных аспектов разработки ПО ОО-способом - возможность создавать его на основе существующих библиотек. ОО-среда должна обеспечивать хорошие библиотеки и механизмы создания новых библиотек.
Базовые библиотеки
Изначально в информатике изучаются фундаментальные структуры данных - множества, списки, деревья, стеки; связанные с ними алгоритмы - сортировки, поиска, обхода, сопоставления с образцом. Эти структуры и алгоритмы вездесущи в разработках ПО. Нередко, когда в своей системе очередной разработчик повторно их реализует. Это не только расточительно, но и пагубно отражается на качестве ПО, поскольку вряд ли отдельный разработчик, реализующий структуру данных не как цель саму по себе, а в качестве компонента некоторого приложения, достигнет оптимальной надежности и производительности.
ОО-среда разработки должна обеспечить повторно используемые классы, удовлетворяющие общим потребностям.
Должны быть доступны повторно используемые классы, реализующие фундаментальные структуры данных и алгоритмы.
Графика и пользовательские интерфейсы
Многие современные системы ПО интерактивны. При взаимодействии с пользователем широко используется графика и удобный, чаще всего графический интерфейс. Это одна из областей, где ОО-модель оказалась наиболее впечатляющей и полезной. Разработчики должны иметь возможность использовать графические библиотеки для быстрого и эффективного построения интерактивных приложений.
Должны быть доступны повторно используемые классы для разработки приложений, обеспечивающих пользователей приятными графическими пользовательскими интерфейсами.
Механизмы эволюции библиотек
Разработка высококачественных библиотек - долгая и трудная задача. Невозможно гарантировать, что построенные библиотеки сразу будут совершенными. Следовательно, важной проблемой является обеспечение разработчиков библиотеки возможностью обновлять и модифицировать их проекты, не нанося вреда существующим системам, основанным на библиотеках. Этот важный критерий эволюции мы отнесли к категории библиотек, но он относится также и к категории метода и языка.
Должны быть доступны механизмы, облегчающие эволюцию библиотек с минимальными нарушениями работы ПО клиентов.
Механизмы индексации в библиотеках
Еще одна насущная проблема библиотек - это необходимость механизмов идентификации классов для удовлетворения определенных нужд. Этот критерий затрагивает все три категории: библиотеки, язык (поскольку должен быть способ вводить индексирующую информацию в текст каждого класса) и инструментарий (для обработки запросов для классов, удовлетворяющих определенным условиям).
Библиотечные классы должны быть снабжены индексирующей информацией, допускающей поиск, основанный на свойствах.
Чтобы глубоко понять концепции, предпочтительно читать эту книгу последовательно, однако читатели, желающие дополнить данный теоретический обзор, могут, прежде чем идти дальше, посмотреть, как работает метод на практическом примере. Для этого следует обратиться ккурса "Основы объектно-ориентированного проектирования", где рассматривается конкретная задача и сравнивается ОО-решение с решением, использующим традиционную технику.
Изучение этой лекции в основном самодостаточно, так что вы сможете понять решение, не читая промежуточные лекции. Но если вы заглянете туда, то должны обещать вернуться назад, чтобы продолжить изучения материала последовательно, начиная с.
Библиографические ссылки и объектные ресурсы
Введение в ОО-критерии - это то место, где стоит привести список работ, дающих хорошие введения в объектную технологию в целом.
[Walden 1995] обсуждает самые важные проблемы объектной технологии, обращая особое внимание на анализ и проектирование, эта книга является, вероятно, лучшим справочным руководством по этому вопросу.
[Page-Jones 1995] дает отличный обзор метода.
[Cox 1990] (первое издание относится к 1986 году) основывается на несколько другом взгляде на объектную технологию; книга послужила распространению ОО-концепций среди широкой публики.
[Henderson-Sellers 1991] (второе издание готовится) дает краткий обзор ОО-идей. Книга предназначена для людей, которых их компания просит "пойти и посмотреть, что это такое объектное программирование", содержит готовые для копирования диапозитивные оригиналы, в некоторых случаях очень ценные. Еще один обзор - это [Eliens 1995].
Словарь Объектной Технологии [Firesmith 1995] дает обширный справочный материал по многим аспектам метода.
Все эти книги в различной степени адресованы людям с техническими наклонностями. Существует также необходимость обучать менеджеров.
Книга [M 1995] выросла из лекции, первоначально предназначенной для данной книги, и стала полноправной книгой, в которой объектная технология обсуждается с позиций управляющего персонала. Она начинается небольшой технической презентацией, использующей профессиональные термины, и далее дает анализ вопросов менеджмента (жизненный цикл, управление проектами, политика повторного использования). Еще одна книга с управленческим уклоном, [Goldberg 1995], дает дополнительную перспективу многих важных тем. [Baudoin 1996] делает акцент на вопросах жизненного цикла и важности стандартов.
Возвращаясь к техническим презентациям, три важных книги по ОО-языкам, написанные создателями этих языков, содержат общие методологические обсуждения, делающие их интересными даже для тех читателей, которые не используют эти языки или даже, возможно, неодобрительно к ним относятся. История языков программирования и книг о них показывает, что создатели не всегда наилучшим образом пишут о своих созданиях, но в этом случае они сделали это хорошо. Это книги:
Совсем недавно некоторые начальные учебники по программированию стали использовать ОО-идеи с самого начала, поскольку нет причин позволять "онтогенезу повторять филогенез". Нет необходимости, чтобы бедные студенты, как их предшественники, прошли через всю историю колебаний и ошибок, пока не доберутся до правильных идей. Первый такой текст (насколько я знаю) был [Rist 1995]. Другая хорошая книга, отвечающая тем же потребностям - это [Wiener 1996]. На следующем уровне - учебники для второго курса по программированию. Обсуждение структур данных и алгоритмов, основанное на нотации этой книги - вы найдете в [Gore 1996] и [Wiener 1997]; [Jezequel 1996] представляет принципы ОО-инженерии ПО. Преподавание технологии обсуждается также вкурса "Основы объектно-ориентированного проектирования".
Группа новостей Usenet comp.object, на нескольких сайтах сети, является естественной площадкой обсуждения многих вопросов объектной технологии. Как и все подобные форумы, это смесь хорошего, плохого и ужасного. Раздел Объектной Технологии в Computer (IEEE), который я редактирую с его начала в 1995 году, часто помещает колонки ведущих экспертов.
Журналы, посвященные Объектной Технологии:
Основные международные конференции по объектному ориентированию:
OOPSLA (ежегодная, USA или Canada, см. http://www.acm.org); Object Expo (различное время и разные места, см. http://www.sigs.com); и TOOLS (Технология ОО-языков и систем), организуемая ISE три раза в год.