Для простоты в этом разделе будем предполагать, что проблема сводится к чтению и записи файлов. Для этих операций будем использовать термины "возвратить" (retrieval) и "сохранить" (storage), адекватные терминам ввод и вывод (input, output). Изучаемые механизмы должны быть применимыми при использовании других средств коммуникации, например при посылке и получении объектов по сети.

Для экземпляров таких классов, как POINT или BOOK1 сохранение и возвращение объектов не является какой-либо новинкой. Эти классы, используемые в качестве первых примеров этой лекции, имеют атрибуты таких типов, как INTEGER, REAL и STRING, для которых доступно хорошо понятное внешнее представление. Сохранение или возвращение экземпляра такого класса из файла подобно выполнению операций ввода-вывода записей в языке Паскаль или структур языка С. Для этих хорошо известных технических проблем существуют стандартные решения. Поэтому резонно ожидать, что объектам в хорошем ОО-окружении можно предоставить процедуры общего назначения, скажем read и write, которые подобно clone и copy будут доступны для всех классов.

Но такие механизмы не могут нас полностью устраивать, поскольку они не управляют главным элементом объектной структуры - ссылками. Так как ссылки могут быть представлены адресами памяти или чем-то подобным, то и для них можно найти подходящее внешнее представление. Это не самая трудная часть проблемы. Сложнее обстоит дело с передачей смысла самих ссылок. Ссылки присоединены к объектам и бесполезны в отсутствие этих объектов. Так что, как только мы начинаем иметь дело с нетривиальными объектами - объектами, содержащими ссылки, нас перестают устраивать старые механизмы сохранения и возвращения, работающие только со значениями. Механизмы должны вместе с объектом обрабатывать и всех его связников (dependents) в соответствии со следующим определением:

Определение: связники, прямые связники

Прямыми связниками объекта являются объекты, присоединенные к его ссылочным полям, если таковые имеются.

Связниками объекта являются сам объект и (рекурсивно) связники его прямых связников.

Для структуры объектов, показанной на рис.8.17, было бы бессмысленно сохранить в файле или передать по сети только объект O1. Операция должна включать связников O1 - объекты O2 и O3.

Рис. 8.17.  Три взаимно зависимых объекта

В этом примере любой из трех объектов рассматривает оставшиеся два как своих связников. В примере, показанном на рис.8.18, объект W1 можно сохранить независимо, но сохранение объектов B1 или B2 требует сохранения также и W1.

Рис. 8.18.  Объекты «Book» и «Writer»

Понятие связников неявно присутствует в представлении deep_equal. Вот общее правило:

Принцип Замыкания Сохраняемости (Persistence Closure principle)

Всякий раз, когда механизм сохранения сохраняет объект, он должен сохранять и связников этого объекта. Всякий раз, когда механизм возвращения возвращает объект, он должен возвращать и связников этого объекта, если они еще не были возвращены.

Базисным механизмом, реализующим эти цели, является библиотечный класс STORABLE, включенный в библиотеку Base. Основными компонентами класса STORABLE являются:

store (f: IO_MEDIUM)

retrieved (f: IO_MEDIUM): STORABLE

Вызов x.store (f) сохраняет в файле, связанном с f, объект, присоединенный к x, вместе со всеми его связниками. Объект, присоединенный к x, называют головным объектом хранимой структуры. Порождающий класс для x должен быть потомком STORABLE. Это требуется только для класса головного объекта и не распространяется на связников.

Класс IO_MEDIUM это еще один класс библиотеки Base, предназначенный для работы не только с файлами, но и для передачи данных по сети. Очевидно, f не должно быть void, а присоединенный файл или сетевое устройство должны допускать запись.

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

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