Presenter meets Visitor

Here are the slides from my presentation at NNUG 30.09.2010. (First slide in Norwegian, rest in English) . It is from a real world experience when presenting heterogenous data in a grid. The example walkthrough uses GOF patterns and Single Responsibility to improve the code quality. It starts out with a naive approach and does stepwise refactorings. We get to know the Presenter and the Visitor pattern – which fully takes usage of OO and static languages. The combination of Presenter and Visitor is indeed powerful.

This entry was posted in code and tagged . Bookmark the permalink.

9 Responses to Presenter meets Visitor

  1. Florent Bécart says:

    Thank you for putting this slideshow online. It’s clear and very interesting.

    However, I’m not really fond of the Visitor pattern.
    First, from my point of view, it increased the complexity of the code.
    Also, adding the accept method in IWorkOrderDto has important drawbacks. It makes you modify the Dtos to match the needs of the view/presentation. Dtos become dependant of the IWorkOrderVisitor interface, that’s to say they become aware of the design pattern used for the view/presentation.

    However, the great thing is that once this pattern set up, you can create a new GUI with different presenters/transformers, and simply reuse the IWorkOrderVisitor interface to implement the same design pattern.

    I never experienced the use of this design pattern on a real project, and would like to understand better its advantages. Maybe my if-phobia didn’t develop enough yet, to get a fair picture of it 😉

    On slide “Advantages”, you wrote “When introducing a new WorkOrder type […] add a Visit(..) method to the IWorkOrderVisitor (or else you will get a compile error!)”. I really can’t see why forgetting to add this method would throw a compile error. Maybe you could enlighten me about this particular point.

    • larsroald says:

      Thanks for comment.
      Well personally, I think that having an Accept method is a very small tradeoff compared to what you get. It is far better than downcasting. A lot of devs have tried (unsuccessfully) to avoid this small “littering” – but they always end up with runtime type checking / casting.

      About the compile error you will get:
      1. Let’s say you create a concrete class XWorkOrder : IWorkOrderDto .
      2. Then you will get a compile error because void Accept(IWorkOrderVisitor visitor) of the interface is not implemented.
      3. You go ahead and implement it:
      public void Accept(IWorkOrderVisitor visitor)
      4. Then you get a second compile error because the IWorkOrderVisitor does not have a void Visit(XWorkOrder order). This is important because the Visitor now have to decide at compile-time what to do with the new class ( ~ how to present the new Dto in the View ).

  2. Marc says:

    How about adding a decorator to the DTOs? This way, your DTO objects become completely independent of the visitor and you can still use it to visit the decorated DTOs. Some code that is bot bound to the UI does not need to know there’s something like a visitor that will be accepted just to be able to display the DTO.

    • larsroald says:

      What you are suggesting is what I suggested as a sub-optimal solution in one the refactoring steps.
      But then you are letting the Dto’s do the presentation because they have to inherit from a decorator base class/ interface. This means the the dto has two responsibilities: keeping track of data and presenting the data at the client side. And therefore violating the Single Responsibility Principle. I think Dto’s should be independant of what is happening at the client side. And what if we have a different view (perhaps with a different technology like silverlight / compact framework) that wants to present the Dto in sligtly different way ?
      Or did I misinterpret your comment ?

      • Marc says:

        What I meant was to keep your proposed solution – which I find rather nice – and to add decorators to the DTOs. It is the decorator that inherits from the DTO and not the othar way around.
        So now the visitor visits the decorated objects instead of the plain DTOs. That way, the DTOs stay independent of any UI implementation. Wheneven the need for a new DTO arises, you add another decorator that can accept an IWorkOrderVisitor.
        I think this keeps responsibilities nicely separated: the DTO just holds the data, the visitor does the UI work, and the decorators translate the plain DTO to something that can be visited.
        Looking forward for your comments.

      • larsroald says:

        Ah, I see. I like your suggestion – it is very clean.

      • Florent Bécart says:

        When and how would you decorate the DTOs in a clean way?

      • larsroald says:

        Well, that is a problem. I see now that a traditional decorator wouldn’t fit well. We need to use a wrapper / facade instead. And each wrapper would have the respective Dto as input in a setup-method (at the serverside).

        The service would return a list of wrapped Dtos. The service itself need to use two other subServices : GetInboundWorkordersDto(…) and GetOutboundWorkOrdersDto(…) .
        And the wrapper itself would either have to “re-implement” all properties of the underlying Dto or have some method like GetCoreDto() that returned the underlying dto.

        I feel differently about your suggestion now. I really dont think this is worth it.
        The only gain is getting rid of the Accept method at the Dtos.
        But it is cleaner though.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s