Опубликован: 03.10.2011 | Уровень: для всех | Доступ: свободно | ВУЗ: Тверской государственный университет
Лекция 10:

Переменные, присваивание и ссылки

Скрытие информации: доступ к полям

Предшествующее обсуждение показывает, как можно модифицировать поля объекта, соответствующие атрибутам класса. Правила не запрещают клиентам получать доступ к полям, таким как index. Клиент может, например, использовать выражение Line8.index, чтобы узнать текущее значение поля:

Line8.start
Line8.forth
Console.show (Line8.index)

В результате значение 2 будет показано в окне консоли.

В других ситуациях может требоваться полное скрытие информации, с полным запрещением и модификации, и доступа к атрибуту. Например, LINE имеет метод id_generator, используемый для своих внутренних потребностей, который ни в какой форме не должен быть доступен клиентам. Для этого достаточно раздел feature, содержащий объявление атрибута, записать в следующей форме: feature {NONE}.

В этом случае все методы и атрибуты этого раздела станут недоступны клиентам. Если просматривать класс LINE, то можно увидеть предложение feature, стоящее непосредственно перед invariant предложением:

feature {NONE} — Инициализация
  id_generator: ID_GENERATOR
    — Внутренняя идентификация текущей линии

В результате выражение Line8.id_generator приводит к ошибке, если оно встречается у любого клиента (проверьте это и посмотрите на сообщение компилятора). Соответственно, этот метод не входит в документацию класса. Взгляните на контрактный облик класса LINE— вы не увидите никакого упоминания об id_generator. Этот метод можно встретить только в неквалифицированных вызовах в методах самого класса LINE. Например, процедура extend использует (проверьте это самостоятельно) присваивание:

i := id_generator.generated_id

NONE является именем специального класса. Когда мы будем изучать наследование, увидим его место в общем миропорядке.

9.3. Виды компонентов класса (features)

Теперь мы знакомы со всеми компонентами класса и способны понять их полную классификацию.

Точка зрения клиента

С позиций клиента доступны заданные в интерфейсе методы класса, которые могут быть запросами или командами. Метод может:

  • возвращать результат, тогда он является запросом;
  • не возвращать результат, но может изменить состояние целевого объекта, тогда он является командой.

В первом случае есть две возможности, зависящие от того, как автор класса реализовал запрос.

  • Он мог выбрать память, тогда значение запроса будет храниться в соответствующем поле каждого объекта класса. Это означает реализацию запроса атрибутом класса. Как следствие, команды класса ответственны за изменение этого поля всякий раз, когда это необходимо, например, forth изменяет index.
  • Вместо хранения запроса можно выбрать его вычисление. Всякий раз, когда понадобится значение, оно будет вычисляться в соответствии с заданным алгоритмом. В этом случае запрос реализуется функцией. Примером является функция south_end.

Эта классификация показана на следующем рисунке.

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

Классификация: взгляд клиента

Рис. 9.6. Классификация: взгляд клиента

Понятие "запрос" важно как общая категория для атрибутов и функций. Клиенту безразлично, как реализован запрос. Хотя различие отражается в тексте класса, но оно не проявляется в интерфейсе класса. Взгляните еще раз на контрактный облик класса LINE — вы сможете увидеть следующие друг за другом (один в предложении —Access, другой — в Measurement) интерфейсы двух запросов:

index: INTEGER
  — Индекс текущей станции на линии.

и

count: INTEGER
  — Число станций на этой линии.

Внешне они схожи. Но если посмотреть фактический текст класса, а не его контрактный облик, то index появляется как атрибут, в то время как count — это функция:

count: INTEGER
    — Число станций на этой линии.
  do
    Result := metro_stops.count
  end

Ничто в контрактном облике не указывает на эту разницу: для клиента — это запросы. Политика, рассматривающая атрибуты и функции идентичными в контрактном облике класса, отражается в принципе разработки ПО.

Почувствуй методологию
Принцип унифицированного доступа

Когда клиенты класса используют запрос, нет никакой логической разницы, как он реализован - хранением в памяти или вычислением.

Атрибут задает хранение в памяти, функция — вычисление. То, что нет "логической разницы", не означает отсутствия "функциональной разницы". Разница может ощущаться в эффективности. Атрибуты требуют больше памяти, функции больше времени на их выполнение.

Выбор между двумя решениями всегда представляет извечный компромисс "память — время". Из этого вытекает важность принципа унифицированного доступа, разработчику вначале трудно выбрать лучшее решение. В ходе разработки и сопровождения проекта решение может меняться, иногда несколько раз. Принцип защищает клиента от этих изменений: нотация some_object.some_query применима в обоих случаях. Если бы доступ к атрибутам и функциям использовал различный синтаксис, то при изменениях пришлось бы обновлять существенную часть всей системы, что затрагивало бы всех клиентов данного класса.

Обсудим, как этот принцип связан с политикой скрытия информации.

  • При проектировании класса разумно предоставлять клиентам доступ к атрибуту (чтение значения), особенно с учетом того, что они не знают, как реализован их запрос — атрибутом или функцией.
  • Было бы неправильно позволять клиентам непосредственно присваивать значение атрибуту. Заметим, что среди прочего это позволило бы клиентам понять, что они имеют дело с атрибутом.

Позиция поставщика

Рассмотрим проблему классификации компонентов класса с позиций его разработчика:

Классификация: взгляд поставщика

Рис. 9.7. Классификация: взгляд поставщика

Совмещая два рисунка, получим полную картину ( рис. 9.8).

Классификация: полная картина

Рис. 9.8. Классификация: полная картина

Следует знать точное определение всех терминов, перечисленных на рисунке, их роль в построении классов, их использование клиентами класса.

Кирилл Юлаев
Кирилл Юлаев
Федор Антонов
Федор Антонов

Здравствуйте!

Записался на ваш курс, но не понимаю как произвести оплату.

Надо ли писать заявление и, если да, то куда отправлять?

как я получу диплом о профессиональной переподготовке?