LINUX.ORG.RU

Вопрос по паттерну visitor

 ,


0

1

допустим, у меня есть Acceptor с методом accept и Visitor с методом visit. Соответственно я пишу что то вроде

acceptorInstance.accept(visitorInstance)
Что бы изменилось, если бы у меня был Visitor c методом visit, при этом Acceptor не имел accept, и я бы писал как то так:
visitorInstance.visit(acceptorInstance)
? Что от этого меняется?



Последнее исправление: asteroidcollide (всего исправлений: 3)

Ну код то в твоём случае, ёпта, будет в визиторе, а не в аксепторе. А смысл паттерна в том что каждый аксептор будет выполнять подходящий на его взгляд по смыслу код для данного конкретного визитора. не?

т.е. у каждого аксептора может быть свой уникальный accept. а визитор просто вызывает этот аксепт на себе когда визитирует.

анонимус, ты не серьёзно относишься к учёбе. уже пора книжки не просто выкидывать со словами «я вот тут не понял, значит автор - дурак». А пытаться понять что авторы хочет до тебя донести.

AndreyKl ★★★★★
()
Последнее исправление: AndreyKl (всего исправлений: 1)
Ответ на: комментарий от AndreyKl

ну код то ёпта, будет в визиторе а не в аксепторе.

Это почему же? В визиторе в любом случае должен быть описан интерфейс аксептора, проще говоря, он должен знать имена его слотов.

смысл в том что каждый аксептор будет выполнять подходящий на его взгляд по смыслу код для данного конкретного визитора. не?

Да вроде нет, аксептор просто «пускает» визитора, визитор сам «знает» что ему делать внутри.

asteroidcollide
() автор топика
Ответ на: комментарий от AndreyKl

у каждого аксептора может быть свой уникальный accept.

В каком смысле «уникальный»?

а визитор просто вызывает этот аксепт на себе когда визитирует

Ну, если судить по этому вот примеру

https://ru.wikipedia.org/wiki/Посетитель_(шаблон_проектирования)#Python

наоборот

asteroidcollide
() автор топика
Ответ на: комментарий от asteroidcollide

В каком смысле «уникальный»?

в прямом. у одного будет

function accept(V visitor) {
this.a = this.b + visitor.getC()
}

а у другого

function accept(V visitor) {
this.b = this.a - visitor.getC()
}


наоборот

там не наоборот. просто подразумевается что визиторов в общем случае тоже может быть несколько реализаций и у каждого своя getC().

AndreyKl ★★★★★
()
Последнее исправление: AndreyKl (всего исправлений: 1)
Ответ на: комментарий от AndreyKl

в прямом.

А где у тебя там уникальный визитор? Ты визитора берешь в качестве аргумента в данном случае, он может быть одним и тем же объектом. А если они даже и разные, это не в классе определяется, а в вызывающем коде, в данном случае?

там не наоборот. просто подразумевается что визиторов в общем случае тоже может быть несколько реализаций и у каждого своя getC().

Это ничего не отменяет. Там визитор подается в качестве аргумента. А ты пишешь прямо противоположное

каждый аксептор будет выполнять подходящий на его взгляд по смыслу код для данного конкретного визитора.

аксептор там ничего не выбирает, он просто принимает визитора в качестве аргумента

asteroidcollide
() автор топика
Ответ на: комментарий от asteroidcollide

я конечно слегка привераю, надо так

function accept(V visitor) {
visitor.visitA(this)
}


а у другого
function accept(V visitor) {
visitor.visitB(this)
}


просто подразумевается что визиторов в общем случае тоже может быть несколько реализаций и у каждого свои visitA() и visitB.

AndreyKl ★★★★★
()
Ответ на: комментарий от asteroidcollide

прости меня о анонимус, я банду 4х читал 10 лет назад и сейчас меня больше увлекают другие вещи, детали мог и подзабыть. смотри ответ выше, вроде верный.

AndreyKl ★★★★★
()
Ответ на: комментарий от AndreyKl

просто подразумевается что визиторов в общем случае тоже может быть несколько реализаций и у каждого свои visitA() и visitB.

Это само сабой, но это не имеет отношения к вопросу, как бы. Ясно что и у визитора и у аксептора может быть множество реализаций

asteroidcollide
() автор топика
Ответ на: комментарий от AndreyKl

Да не, я ниче не понял, на самом деле:) Мне этот паттерн кажется тавтологией. Я уже второй день бьюсь над тем чтобы его понять:)

asteroidcollide
() автор топика
Ответ на: комментарий от AndreyKl

Вот простой пример

Acceptor := Object clone do(
   a := 0
   accept := method(visitor, visitor visit(self))
)

Visitor := Object clone do(
   visit := method(object, object a := object a + 1) 
)

acceptor := Acceptor clone
visitor := Visitor clone

acceptor accept(visitor)
visitor visit(acceptor)

writeln(acceptor a) // ->2
мы что с паттерном, что без него, делаем то же самое. Так в чем смысл?

asteroidcollide
() автор топика
Ответ на: комментарий от asteroidcollide

ха, случается)

на самом деле идея простая: есть набор операций и набор объектов (например, умножение и сложение и числа). Но операция зависит от объекта (умножение и сложение разные для обынчых и комплексных чисел). Визитор нужен чтобы добавлять операции не трогая объекты.

смотри

у тебя есть числа - комплексные и обычные. ты их загоняешь в список.

и ты хочешь с ними что то делать, то ли возводить в квадрат, то ли складывать с собой.

для этого описываешь два класса для чисел. потом проходишься по массиву и делаешь accept

// если хочешь сложить с собой
operator = new SlogiSSoboy
foreach(arr as c) c.doOperation(operator)


// если хочешь возвести в квадрат
operator = new VozvediVKvadrat
foreach(arr as c) c.doOperation(operator)



а внутри чисел

// внутри обычного числа
doOperation = function(visitor) {
visitor.operiruiSObichnim(this)
}

-----
// внутри комплексного числа
doOperation = function(visitor) {
visitor.operiruiSComplexnym(this)
}


и тут ты понимаешь, что хотел бы добавить ещё и деление на себя. и ты нре хочешь трогать иерархию чисел (трудозатратно). поэтому ты создаёшь новый визитор. создаёшь у него два метода operiruiSObichnim и operiruiSKompleksnim и просто посылаешь этот визитор по своей иерархии в нужный момент. получилось что ты основную иерархию (числа в нашем случае) не трогал, а операцию добавил.

AndreyKl ★★★★★
()
Последнее исправление: AndreyKl (всего исправлений: 2)
Ответ на: комментарий от AndreyKl

Я не совсем понимаю, что в данном контексте означает «вырожденный», но по-моему, любой пример применения паттерна можно переписать таким образом без него(в том числе и пример на питоне с википедии, на который я давал ссылку), это общий случай:)

asteroidcollide
() автор топика
Ответ на: комментарий от asteroidcollide

вырожденный значит у тебя один визитор, один аксептор и ты добавлять ничего не хочешь. так просто вызови метод и не парься. визитор то нужен когда? когда ты хочешь добавить операцию для иерархии, а менять иерархию саму не хочешь по каким то причинам. вот отсюда и гляди.

ну и да, я не знаю, читал ли ты про множественную диспечеризацию? визитор - пример двойной диспечеризации. может оттуда будет проще разобраться.

AndreyKl ★★★★★
()
Ответ на: комментарий от AndreyKl

значит у тебя один визитор, один аксептор и ты добавлять ничего не хочешь

Да ничего подобного

Acceptor := Object clone do(
   a := 0
   accept := method(visitor, visitor visit(self))
)

Visitor := Object clone do(
   increment ::= nil
   visit := method(object, object a := object a + increment) 
)

Visitor1 := Visitor clone setIncrement(1)
Visitor2 := Visitor clone setIncrement(2)

acceptor1 := Acceptor clone
visitor1 := Visitor1 clone
acceptor2 := Acceptor clone
visitor2 := Visitor2 clone

acceptor1 accept(visitor1)
visitor1 visit(acceptor1)
acceptor2 accept(visitor2)
visitor2 visit(acceptor2)

writeln(acceptor1 a, acceptor2 a)
#>>>>24

Я уже пытался подойти с этого бока, даже написал наколеночную реализацию мультидиспетчеризации, но все равно ничего не понял:)

asteroidcollide
() автор топика
Ответ на: комментарий от asteroidcollide

ты ленишься:
- элементарного окружения нет (хотя бы массива разных объектов способных принимать визитора)
- операцию ты не добавил

что ты показать хотел? думаю, дальше дискутировать бессмысленно.

AndreyKl ★★★★★
()
Ответ на: комментарий от AndreyKl

хотя бы массива разных объектов способных принимать визитора

то есть загнать acceptor1 и acceptor2 в массив и пройтись по ним форичем для пруф ов концепт, так чтоли?:)

операцию ты не добавил

не вижу препятствий, скажи только куда и какую:)

asteroidcollide
() автор топика
Ответ на: комментарий от asteroidcollide

то есть загнать visitor1 и visitor2 в массив и пройтись по ним форичем для пруф ов концепт, так чтоли?:)
не вижу препятствий, скажи только куда и какую:)

я тебе сказал в примере который я дал выше. просто разберись и повтори его. там всё понятно.

ты ведь даже не прочитал, тебе лень, ты и так умный. так нафига я тогда писал, время тратил.. извини, больше ответов в этом треде не читаю.

AndreyKl ★★★★★
()
Ответ на: комментарий от AndreyKl

что ты показать хотел?

А ты что, забыл, что ты в предыдущем сообщении говорил?

значит у тебя один визитор, один аксептор и ты добавлять ничего не хочешь

asteroidcollide
() автор топика
Ответ на: комментарий от AndreyKl

Все, вроде понял я в чем смысл твоего примера. Суть в том, что твой массив содержит разные типы, у которых несовместимый интерфейс(отсутствует полиморфизм), а визитор разруливает эти противоречия, для унификации.

Понял вроде, спасибо за объяснения.

Мысля приходит опосля. Просто в моем примере интерфейс у разных типов один, поэтому я сразу не срубил фишку:)

asteroidcollide
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.