∙ setUnion Объединяет с другим множеством.
∙ intersection Находит пересечение с другим множеством.
∙ difference Удаляет элементы, которые содержатся в другом множестве.
∙ extent Возвращает количество элементов в множестве.
∙ isEmpty Возвращает 1, если множество пусто.
∙ isMember Возвращает 1, если данный элемент принадлежит множеству.
∙ isSubset Возвращает 1, если множество является подмножеством другого множества.
∙ isProperSubset Возвращает 1, если множество является собственным подмножеством другого множества.
Подобным же образом можно определить протокол класса BinaryTree:
∙ clear Уничтожает дерево и всех его потомков.
∙ insert Добавляет новый узел в корень дерева.
∙ append Добавляет к дереву потомка.
∙ remove Удаляет потомка из дерева.
∙ share Структурно делит данное дерево.
∙ swapChild Переставляет потомка с деревом.
∙ child Возвращает данного потомка.
∙ leftChild Возвращает левого потомка.
∙ rightChild Возвращает правого потомка.
∙ parent Возвращает родителя дерева.
∙ setItem Устанавливает элемент, ассоциированный с деревом.
∙ hasChildren Возвращает 1, если у дерева есть потомки.
∙ isNull Возвращает 1, если дерево нулевое.
∙ isShared Возвращает 1, если дерево структурно разделено.
∙ isRoot Возвращает 1, если дерево имеет корень.
∙ itemAt Возвращает элемент, ассоциированный с деревом.
Для схожих операций мы используем схожие имена. При разработке интерфейса мы также проверяем полученное решение на соответствие критериям достаточности, полноты и примитивности (см. главу 3).
Классы поддержки
При реализации класса, ответственного за манипуляции с текстовыми строками, мы столкнулись с тем, что возможностей, предоставляемых классами поддержки Bounded и Unbounded, явно недостаточно. Ограниченная форма, в частности, оказывается неэффективной для работы со строками с точки зрения памяти, так как мы должны инстанцировать эту форму в расчете на максимально возможную строку, и следовательно понапрасну расходовать память на более коротких строках. Неограниченная форма, в свою очередь, неэффективна с точки зрения быстродействия: поиск элемента в строке может потребовать последовательного перебора всех элементов связного списка. По этим причинам нам пришлось разработать третий, "динамический" вариант:
∙ Динамический Структура хранится в "куче" в виде массива, длина которого может уменьшаться или увеличиваться.
Структура хранится в "куче" в виде массива, длина которого может уменьшаться или увеличиваться.
Соответствующий класс поддержки Dynamic представляет собой промежуточный вариант по отношению к ограниченному и неограниченному классам, обеспечивающий быстродействие ограниченной формы (возможно прямое индексирование элементов) и эффективность хранения данных, присущую неограниченной форме (память выделяется только под реально существующие элементы).
Ввиду того, что протокол данного класса идентичен протоколу классов Bounded и Unbounded, добавление к библиотеке нового механизма не составит большого труда. Мы должны создать по три новых класса для каждого семейства (например, DynamicString, GuardedDynamicString и SynchronizedDynamicString). Таким образом, мы вводим следующий класс поддержки:
template
Dynamic(unsigned int chunkSize);
protected:
Item* rep; unsigned int size; unsigned int totalChunks; unsigned int chunkSize; unsigned int start; unsigned int stop; void resize(unsigned int currentLength, unsigned int newLength, int preserve - 1); unsigned int expandLeft(unsigned int from); unsigned int expandRight(unsigned int from); void shrinkLeft(unsigned int from); void shrinkRight(unsigned int from);
};
Последовательности разбиваются на блоки в соответствии с аргументом конструктора chunkSize. Таким образом, клиент может регулировать размер будущего объекта.
Из интерфейса видно, что класс Dynamic имеет много общего с классами Bounded и Unbounded. Отличия в реализации трех типов классов каждого семейства будут минимальны.
Займемся теперь классом ассоциативных массивов. Его реализация потребует новой переработки ограниченной, динамической и неограниченной форм. В частности, поиск элемента в ассоциативном массиве требует слишком много времени, если его приходится вести перебором всех элементов. Но производительность можно значительно увеличить, используя открытые хеш-таблицы.