Skip to content

Instantly share code, notes, and snippets.

@maplemap
Forked from DmitriiNazimov/pattern-visitor.js
Created July 19, 2020 09:26
Show Gist options
  • Save maplemap/d59e51b68c02918daae09574011337c1 to your computer and use it in GitHub Desktop.
Save maplemap/d59e51b68c02918daae09574011337c1 to your computer and use it in GitHub Desktop.
[JS ES6 Паттерн ПОСЕТИТЕЛЬ (visitor)] #js #ES6 #ООП #Паттерны
/**
*
* ПАТТЕРН ПОСЕТИТЕЛЬ (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