LINUX.ORG.RU

Страшный Visitor в Java

 ,


1

1

Вопрос один: почему все пишут его как на убогих плюсах?

Вот пример: http://en.wikipedia.org/wiki/Visitor_pattern#Sources

Нетрудно догадаться что если вместо мерзенького:

interface ICarElementVisitor {
    void visit(Wheel wheel);
    void visit(Engine engine);
    void visit(Body body);
    void visit(Car car);
}

Написать благословленное

interface ICarElementVisitor {
    void visit(ICarElement element);
}

То мы получим одни преимущества:

1. при добавлении нового типа элемента ничего не надо переделывать

2. когда visitor выполняет общий для любого элемента код (это 99% случаев) нам не придется писать тампаксы в каждом visit

3. вместо жирного интерфейса (да в java без них никуда, чего стоит простой Collection) получаем функциональный - где можно легко и не принужденно использовать lambda

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

Deleted

Это уже не визитор будет. Да и тормозить будет. То, что при добавлении нового типа элемента надо переделывать, это не баг, это фича визитора, для чего он и делается – чтобы не забыть добавить во все алгоритмы обработку нового типа.

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

Это уже не визитор будет.

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

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

вот я тебя и поймал, ты значит и книгу не читал и выдумал новую «философию на крови»

Deleted ()

в убогом стиле тех недоязычков где даже RTTI нету

В твоем коде RTTI не используется, обычный виртуальный метод, который есть и в C++. И непонятно, зачем тут visitor, засунь этот метод в базовый класс и всё.

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

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

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

Расскажи, как ты перепишешь CarElementDoVisitor? Вот так?

class CarElementDoVisitor implements ICarElementVisitor {
    public void visit(Wheel wheel) {
        System.out.println("Kicking my " + wheel.getName() + " wheel");
    }
 
    public void visit(ICarElement element) {
        System.out.println("Kicking my " + element.getElementName());
    }
}

Не прокататит, классы менять нельзя — метода getElementName в них нет. Сделаешь хеш-таблицу Map<Class<? extends ICarElement>, String> для имен объектов? Можно, но одно из назначений visitor'а в том чтобы избежать downcasting'а и rtti.

crowbar ()
Ответ на: комментарий от anonymous

в яве есть instanceof и getClass ты можешь загнать строки, или ввести IPrinter и его реализацию для фиксированных строк ConstantPrinter в map

можно ввести IPrintable и нарисовать if(element instanceof) .... else { element.toString() }

можешь нарисовать if else if else

в любом случае есть _множество_ возможностей для решения задачи, в случае «каноничной» реализации - за тебя уже сделали выбор

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

Deleted ()
Ответ на: комментарий от crowbar

Можно, но одно из назначений visitor'а в том чтобы избежать downcasting'а и rtti.

в крестах на ммоент изобретения сабжа не было стандартного RTTI

и почитай чтоли design patterns GoF, там ничего нет из твоих фантазий про назначение визитора, зато обилие методов приводится как недостаток

Deleted ()

Почему же тогда большинство тупо копирует код ... может я чего-то не знаю?

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

где даже RTTI нету

RTTI может стоить очень дорого, разумно стараться избегать его на массовых операциях. Это к instanceof и т.п.

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

Ты еще рефлексию предложи.

в крестах на ммоент изобретения сабжа не было стандартного RTTI

ну у тебя есть rtti в java вот и пиши свои портянки из if(obj instanceof), зачем тебе visitor.

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

Ты еще рефлексию предложи.

предлагаешь писать на ассбемлере?

Deleted ()
Ответ на: комментарий от mashina

RTTI может стоить очень дорого, ... Это к instanceof и т.п.

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

ps. если боишься instanceof в java то посмотри потроха spring

Deleted ()

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

type Wheel = { name : string ; ... }
type Engine = { ... }
type Body = { ... }
type CarElement = CarWheel of Wheel
                | CarEngine of Engine
                | CarBody of Body

let printCarElement = function
    | Wheel { name = n } -> printfn "Wheel %s" n
    | Engine _ -> printfn "Engine"
    | Body _ -> printfn "Body"
Begemoth ★★★★★ ()
Последнее исправление: Begemoth (всего исправлений: 1)
Ответ на: комментарий от Deleted

если боишься instanceof в java то посмотри потроха spring

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

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

лучше не впадать в крайности

в точку.

Вопрос один: почему все пишут его как на убогих плюсах?

anonymous ()
Ответ на: комментарий от Deleted

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

Использование visitor не характерно для на c/c++, обычно получается обойтись иначе не раздувая код лапшой вроде visit(Wheel wheel) и не влезая в RTTI. Гигантанизм везде подряд это особенность мира java технологий.

mashina ★★★★★ ()

Кстати, автора предисловия к книге Design Patterns: Elements of Reusable Object-Oriented Software зовут Гради Буч. Что созвучно с butch - «мужиковатым» пидорасом.

http://en.wikipedia.org/wiki/Butch_and_femme

anonymous ()

имхо, потому что пример хреновый и не отражает того факта, что у визитящихся объектов мало общего (нет общего интерфейса или суперкласса), что ты визитишь чужие объекты (которым ты не можешь взять и приписать интерфейс).

И даже если ты можешь выдать им общий интерфейс, если таких сочетаний 100500 (из запчастей можно собирать 100500 разных механизмов), засрешь код ненужными интерфейсами (Wheel implements IМашина IПодводнаяЛодка ... 100500).

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

что у визитящихся объектов мало общего (нет общего интерфейса или суперкласса)

он у них будет просто из-за необходимости наличия метода `accept(ICarElementVisitor visitor) {`

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

могу вызвать рефлекшеном любой метод, в зависимости от правил, например, в классах @Repository, вызывать nonTransactionalAccept, а в других просто accept xDD

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

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

почти win, только у тебя в java все объекты наследуются от Object

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

я вообще стараюсь не использовать Visitor и предположил чисто из научного интереса xD

stevejobs ★★★★☆ ()

Как же надоел этот визитор.

Ну пример такой в GoF, один в один с него и переписывают. Но я бы не сказал, что пример плох. Он хорош с точки зрения донесения материала до читателя. Вот просто попробуйте заменить пример из GoF своим вариантом и объяснить неподготовленному читателю - что собственно происходит? В этом плане то, как написано в GoF идеально.

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

И вообще, если помните, там не visit(ElementA) а visitElementA(ElementA), это тоже для ясности, как мне кажется, так написано.

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

там товарищь не осознавал что визитор инкапсулирует внутреннюю структуру, и отделяет логику перечисления\посещения объектов от алгоритма «посещающего» их

Deleted ()

Вот ты ТС алень. В приведенном примере никакой разницы в возможностях между Java и C++ вообще нет. На C++ можно делать так же, как ты предлагаешь делать на Java. Никто так не делает по одной простой причине: это не правильное использование ООП, а просто мозго2.71бство и Си головного мозга, и об этом у Страуструпа отдельно написано. Но если ты ССЗБ, то тебе и флаг в руки.

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

там товарищь не осознавал что визитор инкапсулирует внутреннюю структуру, и отделяет логику перечисления\посещения объектов от алгоритма «посещающего» их

http://orly.jpg.to/

crowbar ()
Ответ на: комментарий от asaw

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

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

Или ты, рассуждая об «убогих плюсах», не в курсе как там делать «instanceof»?

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

тыж заметил что мне пришлось до твоего уровня опуститься и не напоминать тебе про RTTI про который написано в ОП посте

почему в С++ не принято юзать RTTI я тут уже писал Страшный Visitor в Java (комментарий)

после этого ты можешь ссылаться на «не правильное использование ООП» - но выкидывание костылей вводимых из-за убогости недоязычков к этому не относится

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

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

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

Впрочем, кому я отвечаю.

проктикуем

anonymous ()
Ответ на: комментарий от asaw

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

Deleted ()

тю, как это мило. Пользователь одного недоязычка ругает другие недоязычки.

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

Вот даже я, хоть и джявист, продвачую этого дона. Очень забавно вышло.

anonymous ()
Ответ на: комментарий от Begemoth

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

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