
- •Бертран Мейер Основы объектно-ориентированного программирования Аннотация
- •Лекция 1. Качество по
- •Внешние и внутренние факторы
- •Обзор внешних факторов
- •Корректность (Correctness)
- •Устойчивость (Robustness)
- •Расширяемость (Extendibility)
- •Повторное использование (Reusability)
- •Совместимость (Compatibility)
- •Эффективность (Efficiency)
- •Переносимость (Portability)
- •Простота использования (Easy of Use)
- •Функциональность (Functionality)
- •Своевременность (Timeliness)
- •Другие качества
- •О документации
- •Компромиссы
- •Ключевые вопросы
- •О программном сопровождении
- •Ключевые концепции
- •Лекция 2. Критерии объектной ориентации
- •О критериях
- •До какой степени мы должны быть догматичными?
- •Категории
- •Метод и язык
- •Бесшовность (seamlessness)
- •Утверждения (Assertions)
- •Классы как модули
- •Классы как типы
- •Вычисления, основанные на компонентах
- •Скрытие информации (information hiding)
- •Обработка исключений (Exception handling)
- •Статическая типизация (static typing)
- •Универсальность (genericity)
- •Единичное наследование (single inheritance)
- •Множественное наследование (Multiple inheritance)
- •Дублируемое наследование (Repeated inheritance)
- •Ограниченная универсальность (Constrained genericity)
- •Переопределение (redefinition)
- •Полиморфизм
- •Динамическое связывание
- •Выяснение типа объекта в период выполнения
- •Отложенные (deferred) свойства и классы
- •Управление памятью (memory management) и сборка мусора (garbage collection)
- •Реализация и среда
- •Автоматическое обновление (automatic update)
- •Быстрое обновление (fast update)
- •Живучесть (persistence)
- •Документация
- •Быстрый просмотр (browsing)
- •Библиотеки
- •Базовые библиотеки
- •Графика и пользовательские интерфейсы
- •Механизмы эволюции библиотек
- •Механизмы индексации в библиотеках
- •Продолжение просмотра
- •Библиографические ссылки и объектные ресурсы
- •Лекция 3. Модульность
- •Пять критериев
- •Декомпозиция
- •Модульная Композиция
- •Модульная Понятность
- •Модульная Непрерывность
- •Модульная Защищенность
- •Пять правил
- •Прямое отображение
- •Минимум интерфейсов
- •Слабая связность интерфейсов
- •Явные интерфейсы
- •Скрытие информации
- •Пять принципов
- •Лингвистические Модульные Единицы
- •Самодокументирование
- •Унифицированный Доступ
- •Открыт-Закрыт
- •Единственный Выбор
- •Ключевые концепции
- •Библиографические замечания
- •У3.5 Модульность существующих систем
- •У3.6 Управление конфигурацией и наследование
- •Лекция 4. Подходы к повторному использованию
- •Цели повторного использования
- •Ожидаемые преимущества
- •Потребители и производители повторно используемых программ
- •Что следует повторно использовать?
- •Повторное использование персонала
- •Повторное использование проектов и спецификаций
- •Образцы проектов (design patterns)
- •Повторное использование исходного текста
- •Повторное использование абстрактных модулей
- •Повторяемость при разработке по
- •Нетехнические препятствия
- •Синдром nih
- •Фирмы по разработке по и их стратегии
- •Организация доступа к компонентам
- •Несколько слов об индексировании компонентов
- •Форматы для распространения повторно используемых компонентов
- •Техническая проблема
- •Изменения и постоянство
- •Повторно использовать или переделать? (The reuse-redo dilemma)
- •Пять требований к модульным структурам
- •Изменчивость Типов (Type Variation)
- •Группирование Подпрограмм (Routine Grouping)
- •Изменчивость Реализаций (Implementation Variation)
- •Независимость Представлений
- •Факторизация Общего Поведения
- •Традиционные модульные структуры
- •Подпрограммы
- •Пакеты: оценка
- •Перегрузка и универсальность
- •Синтаксическая перегрузка
- •Семантическая перегрузка (предварительное представление)
- •Универсальность (genericity)
- •Основные методы модульности: оценка
- •Ключевые концепции
- •Библиографические замечания
- •Лекция 5. К объектной технологии
- •Ингредиенты вычисления
- •Базисный треугольник
- •Функциональная декомпозиция
- •Непрерывность
- •Проектирование сверху вниз
- •Не только одна главная функция
- •Обнаружение вершины
- •Функции и эволюция
- •Интерфейсы и проектирование по
- •Преждевременное упорядочение
- •Упорядочивание и оо-разработка
- •Возможность повторного использования
- •Производство и описание
- •Проектирование сверху вниз: общая оценка
- •Декомпозиция, основанная на объектах
- •Расширяемость
- •Возможность повторного использования
- •Совместимость
- •Объектно-ориентированное конструирование по
- •Вопросы
- •Выявление типов объектов
- •Описания типов и объектов
- •Описание отношений и структурирование по
- •Ключевые концепции
- •Библиографические замечания
- •Лекция 6. Абстрактные типы данных (атд)
- •Критерии
- •Различные реализации
- •Представления стеков
- •Опасность излишней спецификации
- •Какова длина второго имени?
- •К абстрактному взгляду на объекты
- •Использование операций
- •Политика невмешательства в обществе модулей
- •Согласованность имен
- •Можно ли обойтись без абстракций?
- •Формализация спецификаций
- •Специфицирование типов
- •Универсализация (Genericity)
- •Перечисление функций
- •Категории функций
- •Раздел аксиомы
- •Две или три вещи, которые мы знаем о стеках
- •Частичные функции
- •Предусловия
- •Полная спецификация
- •Ничего кроме правды
- •От абстрактных типов данных к классам
- •Как создавать эффективный класс
- •Роль отложенных классов
- •Абстрактные типы данных и скрытие информации
- •Переход к более императивной точке зрения
- •Назад к тому, с чего начали?
- •Конструирование объектно-ориентированного по
- •За пределами программ
- •Дополнительные темы
- •Еще раз о неявности
- •Соотношение спецификации и проектирования
- •Соотношение классов и записей
- •Альтернативы частичным функциям
- •Полна ли моя спецификация?
- •Item (new) - если это кажется странным, то см. Комментарии ниже.
- •Доказательство достаточной полноты
- •Ключевые концепции
- •Библиографические замечания
- •Упражнения у6.1 Точки
- •У6.2 Боксеры
- •Классы, а не объекты - предмет обсуждения
- •Устранение традиционной путаницы
- •Роль классов
- •Модули и типы
- •Класс как модуль и как тип
- •Унифицированная система типов
- •Простой класс
- •Компоненты
- •Атрибуты и подпрограммы
- •Унифицированный доступ
- •Класс point
- •Основные соглашения
- •Распознавание вида компонент
- •Тело подпрограммы и комментарии к заголовку
- •Предложение indexing
- •Обозначение результата функции
- •Правила стиля
- •Наследование функциональных возможностей общего характера
- •Объектно-ориентированный стиль вычислений
- •Текущий экземпляр
- •Клиенты и поставщики
- •Вызов компонента
- •Принцип единственности цели
- •Слияние понятий модуль и тип
- •Роль объекта Current
- •Квалифицированные и неквалифицированные вызовы
- •Компоненты-операции
- •Селективный экспорт и скрытие информации
- •Неограниченный доступ
- •Ограничение доступа клиентам
- •Стиль объявления скрытых компонент
- •"Внутренний" экспорт
- •Собираем все вместе
- •Общая относительность
- •Большой Взрыв
- •Системы
- •Программа main отсутствует
- •Компоновка системы
- •Классическое "Hello"
- •Структура и порядок: программист в роли поджигателя
- •Обсуждение
- •Форма объявлений
- •Атрибуты или функции?
- •Экспорт атрибутов
- •Доступ клиентов к атрибутам
- •Оптимизация вызовов
- •Архитектурная роль селективного экспорта
- •Импорт листингов
- •Присваивание функции результата
- •Дополнение: точное определение сущности
- •Ключевые концепции
- •Библиографические замечания
- •Объекты
- •Что такое объект?
- •Базовая форма
- •Простые поля
- •Простое представление книги - класс book
- •Писатели
- •Идентичность объектов
- •Объявление ссылок
- •Ссылка на себя
- •Взгляд на структуру объектов периода выполнения
- •Объекты как средство моделирования
- •Четыре мира программной разработки
- •Реальность: "седьмая вода на киселе"
- •Работа с объектами и ссылками
- •Динамическое создание и повторное связывание
- •Инструкция создания
- •Общая картина
- •Для чего необходимо явное создание объектов?
- •Процедуры создания
- •Перекрытие инициализации по умолчанию
- •Статус экспорта процедур создания
- •Правила, применимые к процедурам создания
- •Процедуры создания и перегрузка
- •Еще о ссылках
- •Состояния ссылок
- •Вызовы и пустые ссылки
- •Операции над ссылками
- •Присоединение ссылки к объекту
- •Сравнение ссылок
- •Значение void
- •Клонирование и сравнение объектов
- •Копирование объектов
- •Глубокое клонирование и сравнение
- •Глубокое хранилище: первый взгляд на сохраняемость
- •Составные объекты и развернутые типы
- •Ссылок не достаточно
- •Развернутые типы
- •Роль развернутых типов
- •Агрегирование
- •Свойства развернутых типов
- •Недопустимость ссылок на подобъекты
- •Присоединение: две семантики - ссылок и значений
- •Присоединение
- •Присоединение: ссылочное и копии
- •Гибридное присоединение
- •Проверка эквивалентности
- •Работа со ссылками: преимущества и опасности
- •Динамические псевдонимы
- •Семантика использования псевдонимов
- •Выработка соглашений для динамических псевдонимов
- •Псевдонимы в по и за его пределами
- •Инкапсуляция действий со ссылками
- •Обсуждение
- •Графические соглашения
- •Ссылки и простые значения
- •Форма операций клонирования и эквивалентности
- •Статус универсальных операций
- •Ключевые концепции
- •Библиографические замечания
- •Упражнения у8.1 Книги и авторы
- •У8.2 Личности
- •У8.3 Проектирование нотации
- •Лекция 9. Управление памятью
- •Что происходит с объектами
- •Создание объектов
- •Использование динамического режима
- •Повторное использование памяти в трех режимах
- •Отсоединение
- •Недостижимые объекты
- •Достижимые объекты в классическом подходе
- •Достижимые объекты в оо-модели
- •Проблема управления памятью в оо-модели
- •Три ответа
- •Несерьезный подход (тривиальный)
- •Может ли быть оправдан несерьезный подход?
- •Надо ли заботиться о памяти?
- •Байт здесь, байт там, и реальные покойники
- •Восстановление памяти: проблемы
- •Удаление объектов, управляемое программистом
- •Проблема надежности
- •Проблема простоты разработки
- •Подход на уровне компонентов
- •Управление памятью связного списка
- •Работа с утилизированными объектами
- •Дискуссия
- •Автоматическое управление памятью
- •Необходимость автоматических методов
- •Что в точности понимается под восстановлением?
- •Подсчет ссылок
- •Сборка мусора
- •Механизм сборки мусора
- •Основа сборки мусора
- •Сборка по принципу "все-или-ничего"
- •Продвинутый (Advanced) подход к сборке мусора
- •Алгоритмы параллельной сборки мусора
- •Практические проблемы сборки мусора
- •Класс memory
- •Механизм освобождения
- •Сборка мусора и внешние вызовы
- •Среда с управлением памятью
- •Сложные проблемы
- •Перемещение объектов
- •Механизм сборки мусора
- •Повышенное чувство голода и потеря аппетита (Bulimia and anorexia)
- •Операции сборщика мусора
- •Ключевые концепции
- •Библиографические заметки
- •Упражнения у9.1 Модели создания объектов
- •Горизонтальное и вертикальное обобщение типа
- •Необходимость параметризованных классов
- •Родовые атд
- •Проблема
- •Роль типизации
- •Родовые классы
- •Объявление родового класса
- •Использование родового класса
- •Терминология
- •Проверка типов
- •Правило типизации
- •Операции над сущностями родового типа
- •Типы и классы
- •Массивы
- •Массивы как объекты
- •Свойства массива
- •Размышления об эффективности
- •Синонимичная инфиксная операция
- •Стоимость универсализации
- •Обсуждение: что все-таки не сделано
- •Ключевые концепции
- •Библиографические замечания
- •Упражнения у10.1 Ограниченная универсализация
- •У10.2 Двумерные массивы
- •У10.3 Использование своего формального родового параметра фактически как чужого
- •Лекция 11. Проектирование по контракту: построение надежного по
- •Базисные механизмы надежности
- •О корректности по
- •Выражение спецификаций
- •Формула корректности
- •Сильные и слабые условия
- •Введение утверждений в программные тексты
- •Предусловия и постусловия
- •Класс стек
- •Предусловия
- •Постусловия
- •Педагогическое замечание
- •Контракты и надежность по
- •Права и обязательства
- •Интуиция (Дзен) и искусство программной надежности: больше гарантий и меньше проверок
- •Утверждения не являются механизмом проверки вводимых данных
- •Утверждения это не управляющие структуры
- •Ошибки, дефекты и другие насекомые
- •Работа с утверждениями
- •Класс стек
- •Императив и аппликатив (применимость)
- •Замечание о пустоте структур
- •Проектирование предусловий: толерантное или требовательное?
- •Предусловия и статус экспорта
- •Толерантные модули
- •Инварианты класса
- •Определение и пример
- •Форма и свойства инвариантов класса
- •Инвариант в момент изменения
- •Кто должен обеспечить сохранность инвариантов
- •Роль инвариантов класса в программной инженерии
- •Инварианты и контракты
- •Когда класс корректен?
- •Корректность класса
- •Роль процедур создания
- •Ревизия массивов
- •Связывание с атд
- •Не просто коллекция функций
- •Компоненты класса и атд функции
- •Выражение аксиом
- •Функция абстракции
- •Инварианты реализации
- •Инструкция утверждения
- •Инварианты и варианты цикла
- •Трудности циклов
- •Сделаем циклы корректными
- •Ингредиенты доказательства корректности цикла
- •Синтаксис цикла
- •Использование утверждений
- •Утверждения как средство для написания корректного по
- •Использование утверждений для документирования: краткая форма класса
- •Мониторинг утверждений в период выполнения
- •Каков оптимальный уровень мониторинга?
- •Обсуждение
- •Нужен ли мониторинг в период выполнения?
- •Выразительная сила утверждений
- •Включение функций в утверждения
- •Инварианты класса и семантика ссылок
- •Что дальше
- •Ключевые концепции
- •Библиографические замечания
- •Лекция 12. Когда контракт нарушается: обработка исключений
- •Базисные концепции обработки исключений
- •Исключения
- •Источники исключений
- •Ситуации отказа
- •Обработка исключений
- •Как не следует делать это - c-Unix пример
- •Как не следует делать это - Ada пример
- •Принципы обработки исключений
- •Цепочка вызовов
- •Механизм исключений
- •Спаси и Повтори (Rescue и Retry)
- •Как отказаться сразу
- •Примеры обработки исключений
- •Поломки при вводе
- •Восстановление при исключениях, сгенерированных операционной системой
- •Повторение программы, толерантной к неисправностям
- •Задача предложения rescue
- •Корректность предложения rescue
- •Четкое разделение ролей
- •Когда нет предложения rescue
- •Продвинутая обработка исключений
- •Запросы при работе с классом exceptions
- •Какой должна быть степень контроля?
- •Исключения разработчика
- •Обсуждение
- •Дисциплинированные исключения
- •Должны ли исключения быть объектами?
- •Методологическая перспектива
- •Ключевые концепции
- •Библиографические замечания
- •Упражнения у12.1 Наибольшее целое
- •У12.2 Объект Exception
- •Лекция 13. Поддерживающие механизмы
- •Взаимодействие с не объектным по
- •Внешние программы
- •Улучшенные варианты
- •Использование внешних программ
- •Вопрос совместимости: гибридный программный продукт или гибридные языки?
- •Передача аргументов
- •Инструкции
- •Вызов процедуры
- •Присваивание (Assignment)
- •Создание (Creation)
- •Условная Инструкция (Conditional)
- •Множественный выбор
- •Проверка
- •Отладка
- •Повторение вычислений
- •Выражения
- •Манифестные константы
- •Вызовы функций
- •Текущий объект
- •Выражения с операторами
- •Нестрогие булевы операторы
- •Ввод и вывод
- •Лексические соглашения
- •Ключевые концепции
- •Многоугольники
- •Прямоугольники
- •Основные соглашения и терминология
- •Наследование инварианта
- •Наследование и конструкторы
- •Пример иерархии
- •Полиморфизм
- •Полиморфное присоединение
- •Что на самом деле происходит при полиморфном присоединении?
- •Полиморфные структуры данных
- •Типизация при наследовании
- •Согласованность типов
- •Пределы полиморфизма
- •Экземпляры
- •Статический тип, динамический тип
- •Обоснованы ли ограничения?
- •Может ли быть польза от неведения?
- •Когда хочется задать тип принудительно
- •Полиморфное создание
- •Динамическое связывание
- •Использование правильного варианта
- •Переопределение и утверждения
- •О реализации динамического связывания
- •Отложенные компоненты и классы
- •Движения произвольных фигур
- •Отложенный компонент
- •Эффективизация компонента
- •Отложенные классы
- •Соглашения о графических обозначениях
- •Что делать с отложенными классами?
- •Задание семантики отложенных компонентов и классов
- •Способы изменения объявлений
- •Повторное объявление функции как атрибута
- •Обратного пути нет
- •Использование исходной версии при переопределении
- •Смысл наследования
- •Двойственная перспектива
- •Взгляд на класс как на модуль
- •Взгляд на класс как на тип
- •Наследование и децентрализация
- •Независимость от представления
- •Парадокс расширения-специализации
- •Роль отложенных классов
- •Назад к абстрактным типам данных
- •Отложенные классы как частичные интерпретации: классы поведения
- •Не вызывайте нас, мы вызовем вас
- •Программы с дырами
- •Роль отложенных классов при анализе и глобальном проектировании
- •Обсуждение
- •Явное переопределение
- •Доступ к предшественнику процедуры
- •Динамическое связывание и эффективность
- •Оценка накладных расходов
- •Статическое связывание как оптимизация
- •Кнопка под другим именем: когда статическое связывание ошибочно
- •Ключевые концепции
- •Библиографические замечания
- •У14.5 Классы без объектов
- •У14.6 Отложенные классы и прототип
- •У14.7 Библиотека поиска в таблицах (семестровый проект)
- •У14.8 Виды отложенных компонентов
- •У14.9 Комплексные числа
- •Лекция 15. Множественное наследование
- •Примеры множественного наследования
- •Пример, неподходящий для введения
- •Может ли самолет быть имуществом?
- •Числовые и сравнимые значения
- •Окна - это деревья и прямоугольники
- •Деревья - это списки и их элементы
- •Составные фигуры
- •Брак по расчету
- •Структурное наследование
- •Наследование функциональных возможностей
- •Лунка и кнопка
- •Переименование компонентов
- •Конфликт имен
- •Результат переименования
- •Смена имен и переопределение
- •Подбор локальных имен
- •Играем в имена
- •Использование родительской процедуры создания
- •Плоские структуры
- •Плоская форма класса
- •Применение плоской формы
- •Краткая плоская форма
- •Дублируемое наследование
- •Общие предки
- •По обе стороны океана
- •Совместное использование и репликация
- •Ненавязчивое дублирующее наследование
- •Правило переименования
- •Конфликт переопределений
- •Конфликт при совместном использовании: отмена определения и соединение компонентов
- •Конфликты при репликации: выделение
- •Выделение всех компонентов
- •Сохранение исходной версии при переопределении
- •Пример повышенной сложности
- •Дублируемое наследование и универсальность
- •Правила об именах
- •Обсуждение
- •Переименование
- •Ключевые концепции
- •У15.7 Деревья
- •У15.8 Каскадные или "шагающие" (walking) меню
- •Инварианты
- •Предусловия и постусловия при наличии динамического связывания
- •Как обмануть клиентов
- •Как быть честным
- •Устранение посредника
- •Субподряды
- •Абстрактные предусловия
- •Правило языка
- •Повторное объявление функции как атрибута
- •Замечание математического характера
- •Глобальная структура наследования
- •Универсальные классы
- •Нижняя часть иерархии
- •Универсальные компоненты
- •Замороженные компоненты
- •Запрет повторного объявления
- •Фиксированная семантика компонентов copy, clone и equality
- •Не злоупотребляйте замораживанием
- •Ограниченная универсальность
- •Вектора, допускающие сложение
- •Ограничение родового параметра
- •Игра в рекурсию
- •И снова неограниченная универсальность
- •Попытка присваивания
- •Когда правила типов становятся несносными
- •Проблема
- •Механизм решения
- •Правильное использование попытки присваивания
- •Типизация и повторное объявление
- •Устройства и принтеры
- •Одно- и двусвязные элементы
- •Правило повторного объявления типов
- •Закрепленные объявления
- •Несогласованность типов
- •Примеры из практики
- •Серьезное затруднение
- •Понятие опорного элемента
- •Опорный элемент Current
- •Еще раз о базовых классах
- •Правила о закрепленных типах
- •Когда не используются закрепленные объявления
- •Статический механизм
- •Наследование и скрытие информации
- •Применение
- •Зачем нужна такая гибкость?
- •Интерфейс и повторное использование реализаций
- •Слово в защиту реализаций
- •Два стиля
- •Выборочный экспорт
- •Ключевые концепции
- •Лекция 17. Типизация
- •Проблема типизации
- •Базисная конструкция
- •Статическая и динамическая типизация
- •Правила типизации
- •Реализм
- •Пессимизм
- •Статическая типизация: как и почему
- •Преимущества
- •Аргументы в пользу динамической типизации
- •Типизация: слагаемые успеха
- •"Типизирована ли кроха"?
- •Типизация и связывание
- •Ковариантность и скрытие потомком
- •Ковариантность
- •Параллельные иерархии
- •Своенравие полиморфизма
- •Скрытие потомком
- •Корректность систем и классов
- •Практический аспект
- •Корректность систем: первое приближение
- •Контравариантность и безвариантность
- •Использование родовых параметров
- •Типовые переменные
- •Полагаясь на закрепление типов
- •Глобальный анализ
- •Остерегайтесь полиморфных кэтколлов!
- •Назад, в Ялту
- •Одно правило и несколько определений
- •Полное соответствие
- •Ключевые концепции
- •Библиографические замечания
- •Лекция 18. Глобальные объекты и константы
- •Константы базовых типов
- •Атрибуты-константы
- •Использование констант
- •Константы пользовательских классов
- •Константы с манифестом для этого непригодны
- •Однократные функции
- •Применение однократных подпрограмм
- •Разделяемые объекты
- •Однократные функции с результатами базовых типов
- •Однократные процедуры
- •Параметры
- •Однократные функции, закрепление и универсальность
- •Константы строковых типов
- •Unique-значения
- •Обсуждение
- •Инициализация: подходы языков программирования
- •Строковые константы
- •Unique-значения и перечислимые типы
- •Ключевые концепции
Явные интерфейсы
Четвертое правило является еще одним шагом к укреплению тоталитарного режима в обществе модулей: требуется не только, чтобы любые переговоры ограничивались лишь несколькими участниками и были немногословными; необходимо, чтобы такие переговоры были публичными и гласными!
Всякое общение двух модулей A и B между собой должно быть очевидным и отражаться в тексте A и/или B.
За этим правилом стоят критерии:
[x]. Декомпозиции и композиции. Если нужно разложить модуль на несколько подмодулей или компоновать его с другими модулями, то любая внешняя связь должна быть ясно видна.
[x]. Непрерывности. Должно быть очевидно, какие элементы могут быть затронуты возможным изменением.
[x]. Понятности. Как можно истолковывать действие модуля A , если на его поведение может косвенным образом влиять модуль B ?
Одной из проблем, возникающих при применении правила Явных Интерфейсов, является то, что межмодульная связь может осуществляться не только через вызов процедуры; источником косвенной связи может быть, например, совместное использование данных (data sharing):
Рис. 3.9. Совместное использование данных
Предположим, что модуль A изменяет данные, а модуль B использует тот же элемент данных x . Тогда A и B оказываются фактически связанными через x , хотя между ними может и не быть явной взаимосвязи, например, вызова процедуры.
Скрытие информации
Правило Скрытия Информации можно сформулировать следующим образом:
Разработчик каждого модуля должен выбрать некоторое подмножество свойств модуля в качестве официальной информации о модуле, доступной авторам клиентских модулей.
Применение этого правила означает, что каждый модуль известен всем остальным (то есть разработчикам других модулей) через некоторое официальное описание, или так называемые общедоступные (public) свойства.
Конечно, таким описанием может быть весь текст модуля (текст программы, текст проекта): он и обеспечивает правильное представление о модуле, поскольку это и есть модуль! Но правило Скрытия Информации устанавливает, что в общем случае это не обязательно: описание должно включать лишь некоторые из свойств модуля. Остальные свойства должны оставаться не общедоступными, или закрытыми (секретные) (secret) . Вместо терминов - общедоступные и закрытые свойства - используются также термины: экспортируемые и частные (скрытые) (private) свойства. Общедоступные свойства модуля известны также как интерфейс (interface) модуля (не следует путать с пользовательским интерфейсом системы программирования).
В основе правила Скрытия Информации лежит критерий непрерывности. Предположим, что в некотором модуле происходят изменения, касающиеся лишь его скрытых элементов и не затрагивающие общедоступных свойств; тогда на другие обращающиеся к нему модули, называемые его клиентами , эти изменения не подействуют. Чем меньше общедоступная часть, тем больше шансов на то, что изменения в модуле будут содержаться в его скрытой части.
Можно изобразить модуль, поддерживающий правило Скрытия Информации, в виде айсберга; лишь его верхушка - интерфейс - видна клиентам.
Рис. 3.10. Модуль в условиях скрытия информации
В качестве характерного примера рассмотрим процедуру поиска по ключу атрибутов, хранящихся в таблице, такой как картотека личного состава или таблица идентификаторов компилятора. Эта процедура существенно зависит от способа представления таблицы - последовательный массив или файл, хэш-таблица, двоичное или индексное (B-Tree) дерево и т.д. Скрытие информации означает, что выбранный способ реализации таблицы не влияет на использование такой процедуры. Модули-клиенты не должны страдать от каких-либо изменений в реализации программы.
Правило скрытия информации придает особое значение отделению описания функции от ее реализации, - что делает функция и как она это делает - разные вещи. Помимо критерия непрерывности, это правило связано также с критериями декомпозиции, композиции и понятности. Нельзя независимо разрабатывать модули системы, комбинировать существующие модули или понимать действие отдельных модулей, если неизвестно в точности, что каждый из них может (или не может) ожидать от других модулей.
Какие же из свойств модуля должны быть общедоступными, а какие - скрытыми? Как правило, в общедоступную часть следует включать функциональность, заданную спецификацией модуля, а все, что связано с реализацией этих функциональных возможностей, должно быть скрыто, предохраняя другие модули от последующих изменений реализации программы.
Однако эта рекомендация является нечеткой, так как не дано определение спецификации (specification) и реализации (implementation). Действительно, можно поддаться искушению, изменив определение на прямо противоположное, и утверждать, что спецификация состоит из общедоступных свойств модуля, а реализация - из его скрытых свойств! ОО-подход обеспечит намного более точные рекомендации на основе теории абстрактных типов данных.(См. лекцию 6, в частности "Абстрактные типы данных и скрытие информации".)
Для понимания смысла скрытия информации и применения этого правила должным образом, важно избежать широко распространенного неверного толкования. Несмотря на свое название, скрытие информации не означает защиты информации в смысле обеспечения секретности - запрещения авторам модулей-клиентов доступа к тексту модуля-поставщика (supplier module). На самом деле авторы модулей-клиентов имеют доступ ко всем интересующим их подробностям. В некоторых случаях было бы разумно запретить им это, но такое решение, которое, конечно, может принять руководство проекта, не следует из правила скрытия информации. Скрытие информации, как техническое требование, означает лишь, что модули-клиенты (независимо от того, разрешен ли их авторам доступ к скрытым свойствам модулей-источников) должны рассчитывать только на общедоступные свойства модуля-поставщика. Точнее говоря, должно быть невозможным создание клиентских модулей, правильное функционирование которых зависело бы от скрытой информации.
При формальном подходе к разработке программного обеспечения это определение можно было бы сформулировать следующим образом. Для доказательства корректности модуля необходимо сделать некоторые допущения о свойствах его модулей-поставщиков. Скрытие информации означает, что доказательство может основываться лишь на общедоступных свойствах поставщиков и никоим образом - на их скрытых свойствах.Рассмотрим вновь пример модуля, обеспечивающего реализацию алгоритма поиска в таблице. Некоторый модуль-клиент, который может быть частью системы, реализующей работу с электронными таблицами, обращается к нашему модулю для поиска в таблице определенного элемента. Предположим далее, что наш алгоритм поиска основан на реализации дерева двоичного поиска, но это его свойство является скрытым - и не отражено в интерфейсе. Автор модуля поиска в таблице может сам решать, сообщать ли автору программы электронных таблиц то, как реализован алгоритм поиска. Это решение относится к управлению проектом или, возможно (в случае серийно выпускаемого программного обеспечения), является решением на уровне маркетинга; так или иначе, это не связано с вопросами скрытия информации.
Скрытие информации означает нечто другое: даже если автор программы электронных таблиц знает о том, что поиск основан на дереве двоичного поиска, ему не следует составлять такой модуль-клиент, который правильно функционирует лишь при этой реализации поиска - и перестанет работать при замене алгоритма поиска на какой-либо другой, например, на поиск с хешированием.
Одной из причин вышеупомянутого недопонимания является сам термин "скрытие информации" ("information hiding"), который наводит на мысль о защите физического характера. В этом смысле предпочтительным, по-видимому, мог бы явиться термин "инкапсуляция" ("encapsulation"), иногда используемый в качестве синонима скрытию информации, однако в нашем обсуждении будет по-прежнему использоваться общий термин "скрытие информации".
Из этого обсуждения следует, что ключом к скрытию информации являются не решения по организации доступа к исходному тексту модуля в рамках управления проектом или маркетинговой политики, а строгие языковые правила, определяющие, какие права на доступ к модулю следуют из свойств его источника. В следующей лекции показано, что первые шаги в этом направлении реализованы в таких "языках с инкапсуляцией" как Ada и Modula-2. Объектно-ориентированная технология программирования приведет к более полному решению проблемы.7