Created
August 30, 2019 15:12
-
-
Save DmitriiNazimov/9643db9be2cdfa6f13d43cf21d9c6844 to your computer and use it in GitHub Desktop.
[JS ES6 Паттерн ПОСЕТИТЕЛЬ (visitor)] #js #ES6 #ООП #Паттерны
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
* ПАТТЕРН ПОСЕТИТЕЛЬ (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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment