Опубликован: 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. Классификация: полная картина

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

Кирилл Юлаев
Кирилл Юлаев
Как происходит отслеживание свободного экстента?
Федор Антонов
Федор Антонов
Оплата и обучение
Наталья Алмаева
Наталья Алмаева
Россия
Андрей Лучицкий
Андрей Лучицкий
Россия