Skip to content

Instantly share code, notes, and snippets.

@AlexR0v
Forked from DmitriiNazimov/pattern-visitor.js
Created April 20, 2021 13:06
Show Gist options
  • Select an option

  • Save AlexR0v/9af7bf36c75f3512e17b224ceb46e210 to your computer and use it in GitHub Desktop.

Select an option

Save AlexR0v/9af7bf36c75f3512e17b224ceb46e210 to your computer and use it in GitHub Desktop.

Revisions

  1. @DmitriiNazimov DmitriiNazimov created this gist Aug 30, 2019.
    117 changes: 117 additions & 0 deletions pattern-visitor.js
    Original file line number Diff line number Diff line change
    @@ -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