@@ -0,0 +1,117 @@
/**
*
* ПАТТЕРН ПОСЕТИТЕЛЬ (visitor)
*
* ПОСЕТИТЕЛЬ — используется для расширения возможностей комбинации объектов, т.е. паттерн Посетитель позволяет
* добавлять объектам дополнительные операции, не изменяя их исходный код.
*
* Когда вам нужно выполнить какую-то операцию над всеми элементами сложной структуры объектов, например, деревом.
* Посетитель позволяет применять одну и ту же операцию к объектам различных классов. ИЛИ когда новое поведение имеет
* смысл только для некоторых классов из существующей иерархии.
*
* Шаблон следует использовать, если:
* 1. имеются различные объекты разных классов с разными интерфейсами, но над ними нужно совершать операции, зависящие
* от конкретных классов;
* 2. необходимо над структурой выполнить различные, усложняющие структуру операции;
* 3. часто добавляются новые операции над структурой.
* Реализация:
* 1. Добавьте метод accept(Visitor) в иерархию «элемент».
* 2. Создайте базовый класс Visitor и определите методы visit() для каждого типа элемента.
* 3. Создайте производные классы Visitor для каждой операции, исполняемой над элементами.
* 4. Клиент создаёт объект Visitor и передаёт его в вызываемый метод accept().
*
* Посетителя часто используют своместно с итератором и компоновщиком.
*/
// Элементы в которые будет приходить посетитель
class Monkey {
shout ( ) {
console . log ( 'Ooh oo aa aa!' )
}
accept ( operation ) {
operation . visitMonkey ( this )
}
}
class Lion {
roar ( ) {
console . log ( 'Roaaar!' )
}
accept ( operation ) {
operation . visitLion ( this )
}
}
class Dolphin {
speak ( ) {
console . log ( 'Tuut tuttu tuutt!' )
}
accept ( operation ) {
operation . visitDolphin ( this )
}
}
// Посетители
class Visitor {
visitMonkey ( monkey ) {
throw new Error ( `В ${ this . constructor . name } не описан метод visitMonkey()` )
}
visitLion ( lion ) {
throw new Error ( `В ${ this . constructor . name } не описан метод visitLion()` ) ;
}
visitDolphin ( dolphin ) {
throw new Error ( `В ${ this . constructor . name } не описан метод visitDolphin()` ) ;
}
}
class voiceVisitor extends Visitor {
visitMonkey ( monkey ) {
monkey . shout ( )
}
visitLion ( lion ) {
lion . roar ( )
}
visitDolphin ( dolphin ) {
dolphin . speak ( )
}
}
class jumpVisitor extends Visitor {
visitMonkey ( monkey ) {
console . log ( 'Jumped 20 feet high! on to the tree!' )
}
visitLion ( lion ) {
console . log ( 'Jumped 7 feet! Back on the ground!' )
}
visitDolphin ( dolphin ) {
console . log ( 'Walked on water a little and disappeared' )
}
}
const monkey = new Monkey ( )
const lion = new Lion ( )
const dolphin = new Dolphin ( )
const voicer = new voiceVisitor ( ) ;
const jumper = new jumpVisitor ( ) ;
// Пробуем первого посетителя
monkey . accept ( voicer ) // Ooh oo aa aa!
lion . accept ( voicer ) // Roaaar!
dolphin . accept ( voicer ) // Tuut tutt tuutt!
// Пробуем комбинацию из двух посетителей
// Второй посетитель добавляет новое поведение в классы элементов без изменения самих элементов.
monkey . accept ( voicer ) // Ooh oo aa aa!
monkey . accept ( jumper ) // Jumped 20 feet high! on to the tree!
lion . accept ( voicer ) // Roaaar!
lion . accept ( jumper ) // Jumped 7 feet! Back on the ground!
dolphin . accept ( voicer ) // Tuut tutt tuutt!
dolphin . accept ( jumper ) // Walked on water a little and disappeared