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

Если необходима группа классов, в которой каждый наделен специальными привилегиями, то нет нужды в супермодулях. Простое решение обеспечивается за счет селективного экспорта, что позволяет сохранить классам свой независимый статус.

<p>Импорт листингов</p>

В исходных текстах классов, в предложениях feature, перечислены компоненты, доступные другим классам. Почему бы, в свою очередь, не включать списки компонентов, полученных от других классов? Язык Modula-2 поддерживает, например, объявление import.

Тем не менее, при ОО-подходе это ничего не дает кроме документирования. Для использования компонента f из другого класса C, данный класс должен быть клиентом или потомком этого класса. В первом случае это означает, что f используется как

a.f

но тогда должно присутствовать объявление a:

a: C

недвусмысленно показывающее, что f компонента C. В случае классов потомков информация будет доступна из официальной документации класса, его плоской краткой формы.

Следовательно, нет необходимости в предложении import. ("Плоская краткая форма", лекция 11)

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

<p>Присваивание функции результата</p>

Присваивание функции результата является интересной языковой проблемой, обсуждение которой было начато ранее в данной лекции. Стоит изучить ее подробнее ввиду ее важности и для языков, не использующих ОО-подход.

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

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

f: INTEGER is

do

if some_condition then Result := 10 end

end

возвратит 10 при выполнении условия some_condition на момент вызова и 0 (значение по умолчанию при инициализации INTEGER) в противном случае. Насколько известно автору, техника использования Result была впервые предложена в данной книге. С момента выхода первого издания она была включена по крайней мере в один язык - Borland Delphi. Надо заметить, что она неприемлема для языков, допускающих объявление функций внутри других функций, поскольку имя Result становится двусмысленным. В различных языках наиболее часто используются следующие приемы:

[x]. (A) Заключительные инструкции return (C, C++/Java, Ada, Modula-2).

[x]. (B) Использование имени функции в качестве переменной (Fortran, Algol 60, Simula, Algol 68, Pascal).

Соглашение A основано на инструкции вида return e , выполнением которой завершается функция, возвращая e в качестве результата. Преимущество этого метода в его ясности, поскольку возвращаемое значение четко выделено в тексте функции. Однако он имеет и отрицательные стороны:

[x]. (A1) На практике результат часто определяется в процессе вычислений, включающих инициализацию и ряд промежуточных изменений значения. Возникает необходимость во временной переменной для хранения промежуточных результатов.

[x]. (A2) Методика имеет тенденцию к использованию модулей с несколькими точками завершения. Это противоречит принципам хорошего структурирования программ.

[x]. (A3) В языке должна быть предусмотрена ситуация, когда последняя инструкция, выполненная при вызове функции, не является return. В программах Ada в этом случае возбуждается исключение времени выполнения.

Две последние проблемы разрешаются, если рассматривать return не как инструкцию, а как синтаксическое предложение, являющееся обязательной частью текста любой функции:

function name (arguments): TYPE is

do

...

return

expression

end

Это решение развивает идею инструкции return и устраняет ее наиболее серьезные недостатки. Тем не менее, ни один язык его не использует, оставляя проблему A1 открытой.

Перейти на страницу:

Похожие книги