Visitor pattern - adding new ConcreteElement classes is hard?

前端 未结 4 813
孤街浪徒
孤街浪徒 2021-01-27 06:50

I read a book about the visitor pattern. It gives the same class diagram as in the oodesign\'s website.

It says that adding new ConcreteElement classes is hard. But I di

相关标签:
4条回答
  • 2021-01-27 07:07

    Essentially, visitor pattern is kind of data manipulator, it will

    • Traverse among elements following some rules
    • Do some calculation and manipulation with the data those elements provide

    In one word, visitor pattern will extend the system functionality, without touch the element class definition.

    But does this mean the visitor class must be revised if new concrete element class is added? It depends, I believe, on how the visitor pattern is designed and implemented.

    If separate all the visit methods of visitor into visit functors, and dynamically bind the them together, then it might be easier when extending the how system, for both visitor and visitee.

    Here is an implementation of visitor pattern I wrote several years ago, the code is a bit old and not well polished, but somehow works :)

    https://github.com/tezheng/visitor

    0 讨论(0)
  • 2021-01-27 07:23

    This came up in an SO question just recently. To quote myself from this question, and more specifically the discussion

    The reason a precondition of not changing the set of entities (classes you visit) is because it forces you to implement a new VisitXYZ in each concrete visitor. But I never took much stock in that reasoning becasue if you are supporting a persistance visitor, and a text search visitor, and a print visitor, and a validation visitor and you go and add a new entity you are going to want to implement all that functionality anyway. The visitor pattern (with a common base class) just lets the compiler find the ones you forgot to implement for you.

    So yes it is often said that its hard to implement addition conrete elements (or entities), but in my opinion it is hogwash.

    0 讨论(0)
  • 2021-01-27 07:26

    Well, you have to extend all your visitors.

    You have a caller, some elements that need to be visited, and an element - the visitor - that does the processing of the individual elements. Your goal is to keep the implementation of the elements and the caller fixed, and extend functionality via new visitors.

    Usually you have a lot of the concrete visitors. If you add a new type of element to be processed, you will need to change all the concrete visitors to take this into account.

    Why?

    well, imagine that the caller is "Factory", and you have the elements "Car" and "Bike".

    For operation "Paint" you have to have the methods

    void process(Car c); // Paint a car
    void process(Bike b); // Paint a bike
    

    Likewise for operations "Assemble", "Package", "Wash" etc.

    If you add an element "Scooter", all the operations have to be extended with a new method

    void process(Scooter s); // Handle a Scooter
    

    This is a bit of work. Also you may hit the isse where the element you add is so different from the others that you canøt easily fit them to the operations.

    Wikipedia (http://en.wikipedia.org/wiki/Visitor_pattern) says

    In essence, the visitor allows one to add new virtual functions to a family of classes without modifying the classes themselves; instead, one creates a visitor class that implements all of the appropriate specializations of the virtual function. The visitor takes the instance reference as input, and implements the goal through double dispatch.

    That's a pretty abstract way of saying what I try to say above. Usually you'd add these methods to the elements, but if you can't you have to add the methods to somethign else, and pass that along to do the processing. This is a bit of extra work, but may be worth it, if the situation merits it.

    0 讨论(0)
  • 2021-01-27 07:26

    If you add a new concrete element, then all of your visitor classes will need to add a new visit method for the new element. If you didn't use visitors, you would have to add the equivalent methods to your new concrete element anyway.

    But adding a new method to each your visitors may be harder than adding the equivalent set of methods to a new element class. The reason is that visitors often need to traverse the element tree structure and may need to manage its own state data as it does so. Adding a new visit method may require modifying that state data which involves thinking about how the new method interacts with existing visit methods for other elements.

    It may be simpler to add the equivalent methods to your new element class if you didn't have visitors because you will only need to worry about the internal state of the new concrete element which is more cohesive.

    0 讨论(0)
提交回复
热议问题