Читаем Объектно-ориентированный анализ и проектирование с примерами приложений на С++ полностью

class CipherLetter : public BlackboardObject, virtual public Dependent {public:...

char value() const;int isSolved() const;

...protected:

char letter;Affirmation affirmations;

};

Отметим, что и в этот класс добавлена та же пара селекторов по аналогии с классами слова и предложения. Для клиентов этого объекта нужно предусмотреть защищенные операции доступа к предположениям и утверждениям.

Объект affirmations, включенный в этот класс, содержит коллекцию предположений и утверждений в порядке их выдвижения. Последний элемент коллекции содержит текущее предположение или утверждение. Смысл хранения последовательности решения задачи состоит в возможности обучения источников знании на собственных ошибках. Поэтому в класс Affirmation введены два дополнительных селектора:

mostRecent - возвращает последнее предположение или утверждение;

statementAt - возвращает n-ое высказывание (предположение или утверждение).

Уточнив поведение класса, мы можем принять правильные решения о его реализации. В частности, нам потребуется ввести в класс следующий защищенный объект:

UnboundedOrderedCollection statements;

Этот объект также позаимствован нами из библиотеки фундаментальных классов главы 9.

Теперь обратимся к классу Alphabet

(алфавит). Он содержит данные об алфавитах исходного текста и шифра, а также о соответствии между ними. Эта информация необходима для того, чтобы источники знаний могли узнать о выявленных соответствиях между буквами шифра и текста и тех, которые еще предстоит найти. Например, если уже доказано, что буква с а шифре соответствует букве и исходного текста, то это соответствие фиксируется в алфавите и источники знаний уже не будут делать других предположений в отношении буквы м исходного текста. Для эффективности обработки полезно получать данные о соответствии букв шифра и текста двумя способами: по букве шифра и по букве исходного текста. Определим класс Alphabet следующим образом:

class Alphabet : public BlackboardObject  {public:

char plaintext(char) const;char ciphertext(char) const;int isBound(char) const;

};

Так же, как и в класс CipherLetter, в класс Alphabet необходимо включить защищенный объект

affirmations и определить операции доступа к его состоянию.

Наконец, определим класс Blackboard, который является коллекцией экземпляров класса Blackboardobject и его подклассов:

class Blackboard : public DynamicCollection ...

Поскольку доска есть разновидность коллекции (тест на наследование), мы предпочитаем образовать этот класс методом наследования, а не с помощью включения экземпляра класса DynamicCollectlon. Операции включения в коллекцию и исключения из нее наследуются от класса Collection, а следующие пять операций, специфичных для информационной доски, вводятся нами:

reset - Очистить доску.

assertProblem - Поместить на доске начальные условия задачи.

connect - Подключить к доске источник знании.

issolved -

Истинно, если предложение расшифровано.

retriaveSolution - Значение расшифрованного текста.

Вторая операция устанавливает зависимость между доской и источником знании. На рис. 11-3 приведена итоговая диаграмма классов, связанных с Blackboard. Она в первую очередь отражает отношения наследования. Отношения использования (например, между Assumption и информационной доской) для простоты опушены.  

Рис. 11-3. Диаграмма классов информационной доски.

Обратите внимание на то, что класс Blackboard одновременно и инстанцирует от шаблона DynamicCollection, и наследует от него. Кроме того, становится понятным использование класса Dependent в качестве примеси. Не привязывая этот класс жестко к иерархии Blackboard, мы повышаем шансы на его последующее повторное использование.

Проектирование источников знаний

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

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

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