Читайте также:
|
|
InventoryVisitor к структуре объектов можно применить следующим образом:
Equipment* component; InventoryVisitor visitor;
component->Accept(visitor); cout «"Инвентарная опись "
«component->Name()
«visitor.Getlnventory();
Далее мы покажем, как на языке Smalltalk реализовать пример из описания паттерна интерпретатор с помощью паттерна посетитель. Как и в предыдущем случае, этот пример настолько мал, что паттерн посетитель практически бесполезен, но служит неплохой иллюстрацией основных принципов. Кроме того, демонстрируется ситуация, в которой обход выполняет посетитель.
Структура объектов (регулярные выражения) представлена четырьмя классами, в каждом из которых существует метод accept:, принимающий посетитель в качестве аргумента. В классе SequenceExpression метод accept: выглядит так:
accept: aVisitor
л aVisitor visitSequence: self
Метод accept: в классах RepeatExpression, AlternationExpression и LiteralExpression посылает сообщения visitRepeat:, visitAlternation: и visitLiteral: соответственно.
Все четыре класса должны иметь функции доступа, к которым может обратиться посетитель. Для SequenceExpression это expression! иехргезз!оп2;для AlternationExpression- alternative! и alternative2; для класса RepeatExpression -repetition,а дляLiteralExpression -components.
Конкретным посетителем выступает класс REMatchingVisitor. Он отвечает за обход структуры, поскольку алгоритм обхода нерегулярен. В основном это происходит из-за того, что RepeatExpression посещает свой компонент многократно. В классе REMatching Visitor есть переменная экземпляра inputstate. Его методы практически повторяют методы match: классов выражений из паттерна интерпретатор, только вместо аргумента inputstate подставляется узел, описывающий сравниваемое выражение. Однако они по-прежнему возвращают множество потоков, с которыми выражение должно сопоставиться, чтобы получить текущее состояние:
visitSequence: sequenceExp
inputstate:= sequenceExp expressionl accept: self. A sequenceExp expression2 accept: self.
visitRepeat: repeatExp I finalState I
finalState:= inputstate copy, [inputstate isEmpty]
Паттерн Visitor
whileFalse:
[inputState:= repeatExp repetition accept: self. finalState addAll: inputState]. A finalState
VisitAlternation: alternateExp I finalState originalState I originalState:= inputState.
finalState:= alternateExp alternativel accept: self. inputState:= originalState.
finalState addAll: (alternateExp alternative2 accept: self). A finalState
visitLiteral: literalExp I finalState tStream I finalState:= Set new. inputState do:
[:stream I tStream:= stream copy. (tStream nextAvailable:
literalExp components size) = literalExp components
ifTrue: [finalState add: tStream]
]. A finalState
Известные применения
В компиляторе Smalltalk-80 имеется класс посетителя, который называется ProgramNodeEnumerator. В основном он применяется в алгоритмах анализа исходного текста программы и не используется ни для генерации кода, ни для красивой печати, хотя мог бы.
IRIS Inventor [Str93] - это библиотека для разработки приложений трехмерной графики. Библиотека представляет собой трехмерную сцену в виде иерархии узлов, каждый из которых соответствует либо геометрическому объекту, либо его атрибуту. Для операций типа изображения сцены или обработки события ввода необходимо по-разному обходить эту иерархию. В Inventor для этого служат посетители, которые называются действиями (actions). Есть различные посетители для изображения, обработки событий, поиска, сохранения и определения ограничивающих прямоугольников.
Чтобы упростить добавление новых узлов, в библиотеке Inventor реализована схема двойной диспетчеризации на C++. Для этого служит информация о типе, доступная во время выполнения, и двумерная таблица, строки которой представляют посетителей, а колонки - классы узлов. В каждой ячейке хранится указатель на функцию, связанную с парой посетитель-класс узла.
Марк Линтон (Mark Linton) ввел термин «посетитель» (Visitor) в спецификацию библиотеки для построения приложений X Consortium's Fresco Application Toolkit [LP93].
Паттерны поведения
Родственные паттерны
Компоновщик: посетители могут использоваться для выполнения операции над всеми объектами структуры, определенной с помощью паттерна компоновщик.
Интерпретатор: посетитель может использоваться для выполнения интерпретации.
Дата добавления: 2015-09-11; просмотров: 91 | Поможем написать вашу работу | Нарушение авторских прав |