the Visitor Design Pattern

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • FluffyCat

    the Visitor Design Pattern

    New on November 28, 2005 for www.FluffyCat.com PHP 5 Design Pattern
    Examples - the Visitor Pattern.

    In the Visitor pattern, one class calls a function in another class
    and passes an instance of itself. The called class has special
    functions for each class that can call it.

    With the visitor pattern, the calling class can have new operations
    added without being changed itself.


  • Chung Leong

    #2
    Re: the Visitor Design Pattern


    FluffyCat wrote:[color=blue]
    > New on November 28, 2005 for www.FluffyCat.com PHP 5 Design Pattern
    > Examples - the Visitor Pattern.
    >
    > In the Visitor pattern, one class calls a function in another class
    > and passes an instance of itself. The called class has special
    > functions for each class that can call it.
    >
    > With the visitor pattern, the calling class can have new operations
    > added without being changed itself.
    >
    > http://www.fluffycat.com/SDCMSv2/PHP...terns-Visitor/[/color]

    A class that passes an instance of itself to another class means you
    don't freaking know what you're doing. What's next? The spaghetti
    design pattern?

    Comment

    • Oli Filth

      #3
      Re: the Visitor Design Pattern

      Chung Leong wrote:[color=blue]
      > FluffyCat wrote:[color=green]
      > > New on November 28, 2005 for www.FluffyCat.com PHP 5 Design Pattern
      > > Examples - the Visitor Pattern.
      > >
      > > In the Visitor pattern, one class calls a function in another class
      > > and passes an instance of itself. The called class has special
      > > functions for each class that can call it.
      > >
      > > With the visitor pattern, the calling class can have new operations
      > > added without being changed itself.
      > >
      > > http://www.fluffycat.com/SDCMSv2/PHP...terns-Visitor/[/color]
      >
      > A class that passes an instance of itself to another class means you
      > don't freaking know what you're doing. What's next? The spaghetti
      > design pattern?[/color]

      I think the OP has phrased this badly. He actually has an object
      passing this ($this) to a method in another object, which is hardly
      uncommon practice in most OO languages (e.g. registering a callback
      interface with a child object).

      However, the OP's example is not particularly great, as it's all being
      driven from outside the objects in question.

      --
      Oli

      Comment

      • FluffyCat

        #4
        Re: the Visitor Design Pattern

        I know these patterns can look like spaghetti code at first, but if
        you will be doing any serious OO programming they are extremely
        important. The visitor pattern is absolutely one that is used and
        useful, so it is worth taking the time to understand it.

        Sometimes I can describe these patterns well and sometimes not.
        Judging from the response this is probably a not. Maybe I should have
        said "the current instance of itself" instead, which is what $this is,
        instead of "an instance of itself", which could imply a new instance.
        Maybe instead of describing these patterns I should just have the UML
        and the code. I don't have a tool to create UML for PHP yet, which
        defiantely hurts my examples.

        I try to make these examples as simple as possible, while sticking to
        the original intent of the pattern. In the GoF on page 334 - 335 the
        UML shows anObjectStructu re calling the concrete element (which I call
        the visitee) with accept(Visitor) , the concrete element then calls the
        visitor, which in turn calls a method back in the concrete element.
        So, I've just used my "testVisito r" in place of anObjectStructu re. To
        me, the anObjectStructu re just kicked things off by calling the
        concrete element with a visitor, so I gave the simplest representation
        I could of it. Do you really think this example doesn't meet the
        required intent of the visitor pattern, at least in it's simplest
        form?

        A useful example of the visitor pattern could show the visitor being
        able to create HTML or XML output for the same concrete element. I
        didn't do this because it would "muddy the waters" of the example with
        whatever overhead I'd need to add to produce the HTML and XML. That
        might be a nice second more robust example of the visitor pattern to
        do after I complete my simple versions of all the most important
        design patterns.



        p.s. - even if you weren't exacly crazy about it, thanks very much for
        checking out my pattern example and commenting on it!



        On 29 Nov 2005 04:43:02 -0800, "Oli Filth" <catch@olifilth .co.uk>
        wrote:
        [color=blue]
        >Chung Leong wrote:[color=green]
        >> FluffyCat wrote:[color=darkred]
        >> > New on November 28, 2005 for www.FluffyCat.com PHP 5 Design Pattern
        >> > Examples - the Visitor Pattern.
        >> >
        >> > In the Visitor pattern, one class calls a function in another class
        >> > and passes an instance of itself. The called class has special
        >> > functions for each class that can call it.
        >> >
        >> > With the visitor pattern, the calling class can have new operations
        >> > added without being changed itself.
        >> >
        >> > http://www.fluffycat.com/SDCMSv2/PHP...terns-Visitor/[/color]
        >>
        >> A class that passes an instance of itself to another class means you
        >> don't freaking know what you're doing. What's next? The spaghetti
        >> design pattern?[/color]
        >
        >I think the OP has phrased this badly. He actually has an object
        >passing this ($this) to a method in another object, which is hardly
        >uncommon practice in most OO languages (e.g. registering a callback
        >interface with a child object).
        >
        >However, the OP's example is not particularly great, as it's all being
        >driven from outside the objects in question.[/color]

        Comment

        • Chung Leong

          #5
          Re: the Visitor Design Pattern

          Oli Filth wrote:[color=blue]
          > I think the OP has phrased this badly. He actually has an object
          > passing this ($this) to a method in another object, which is hardly
          > uncommon practice in most OO languages (e.g. registering a callback
          > interface with a child object).[/color]

          That's very different from object A calling a method of object B which
          in turns invokes methods on object A now isn't it? What the OP
          described can be more aptly called the prostitution design pattern.
          Object J has a need that it cannot satisfy, so it visits object H to
          get its private part operated upon. It's sick. It's immoral. Objects
          should only play around with their own thingies.

          Comment

          • FluffyCat

            #6
            Re: the Visitor Design Pattern


            Sure, I guess you could claim visitor is a euphemism for prostitute.
            Keep in mind that these are inherently two consenting objects, and
            what they are doing is legal under the laws of PHP 5 and the Zend
            Engine. OO-phobe sentiment will only keep you mired in procedural
            programming.



            On 29 Nov 2005 22:46:39 -0800, "Chung Leong"
            <chernyshevsky@ hotmail.com> wrote:
            [color=blue]
            >Oli Filth wrote:[color=green]
            >> I think the OP has phrased this badly. He actually has an object
            >> passing this ($this) to a method in another object, which is hardly
            >> uncommon practice in most OO languages (e.g. registering a callback
            >> interface with a child object).[/color]
            >
            >That's very different from object A calling a method of object B which
            >in turns invokes methods on object A now isn't it? What the OP
            >described can be more aptly called the prostitution design pattern.
            >Object J has a need that it cannot satisfy, so it visits object H to
            >get its private part operated upon. It's sick. It's immoral. Objects
            >should only play around with their own thingies.[/color]

            Comment

            • Oli Filth

              #7
              Re: the Visitor Design Pattern


              Chung Leong wrote:[color=blue]
              > Oli Filth wrote:[color=green]
              > > I think the OP has phrased this badly. He actually has an object
              > > passing this ($this) to a method in another object, which is hardly
              > > uncommon practice in most OO languages (e.g. registering a callback
              > > interface with a child object).[/color]
              >
              > That's very different from object A calling a method of object B which
              > in turns invokes methods on object A now isn't it? What the OP
              > described[/color]

              As I said, it's really not a great example (of something that's a good
              idea in principle).

              His example, which basically boils down to:

              $book = new Book();
              $plainVisitor = new PlainDescriptio nVisitor();
              $book->accept($plainV isitor);
              $plainVisitor->getDescription ();

              has a pointless line $book->accept(), i.e. the Book is "doing" the
              work.

              $book = new Book();
              PlainDescriptio nVisitor::descr ibe($book);

              would have made much more sense, or if polymorphism of the visitors is
              a concern:

              $book = new Book();
              $plainVisitor = new PlainDescriptio nVisitor();
              $plainVisitor->visit($book) ;
              ....
              $plainVisitor->getDescription ();

              Either way, it avoids the $book->accept() call, which offers no
              semantic value.
              [color=blue]
              > can be more aptly called the prostitution design pattern.
              > Object J has a need that it cannot satisfy, so it visits object H to
              > get its private part operated upon. It's sick. It's immoral. Objects
              > should only play around with their own thingies.[/color]

              :)

              --
              Oli

              Comment

              • Oli Filth

                #8
                Re: the Visitor Design Pattern

                FluffyCat wrote:[color=blue]
                > I know these patterns can look like spaghetti code at first, but if
                > you will be doing any serious OO programming they are extremely
                > important. The visitor pattern is absolutely one that is used and
                > useful, so it is worth taking the time to understand it.
                >
                > I try to make these examples as simple as possible, while sticking to
                > the original intent of the pattern. In the GoF on page 334 - 335 the
                > UML shows anObjectStructu re calling the concrete element (which I call
                > the visitee) with accept(Visitor) , the concrete element then calls the
                > visitor, which in turn calls a method back in the concrete element.[/color]

                Exactly; what's the point in calling Visitee->accept(Visitor ), whose
                only job is to call Visitor->visit(this)? If ObjectStructure has a
                reference to both Visitor and Visitee, why doesn't it just call
                Visitor->visit(Visitee) ? This would make for a simpler, more intuitive
                arrangement.
                [color=blue]
                > A useful example of the visitor pattern could show the visitor being
                > able to create HTML or XML output for the same concrete element. I
                > didn't do this because it would "muddy the waters" of the example with
                > whatever overhead I'd need to add to produce the HTML and XML.[/color]

                But even that wouldn't require the double dispatch, e.g.:

                $book = new Book();
                $HTMLThing = new HTMLThing();
                $XMLThing = new XMLThing();

                $HTMLThing->display($book) ;
                $XMLThing->display($book) ;


                P.S.: Please don't top-post...

                --
                Oli

                Comment

                • Chung Leong

                  #9
                  Re: the Visitor Design Pattern

                  Oli Filth wrote:[color=blue]
                  >
                  > $book = new Book();
                  > PlainDescriptio nVisitor::descr ibe($book);[/color]

                  Passing input data to a block of reusable code--that's just normal
                  programming. What this world coming to when programmers feel they can't
                  do something if it's not called a design pattern? The end is near, I
                  fear.

                  Comment

                  • FluffyCat

                    #10
                    Re: the Visitor Design Pattern

                    On 30 Nov 2005 08:35:22 -0800, "Oli Filth" <catch@olifilth .co.uk>
                    wrote:
                    [color=blue]
                    >FluffyCat wrote:[color=green]
                    >> I know these patterns can look like spaghetti code at first, but if
                    >> you will be doing any serious OO programming they are extremely
                    >> important. The visitor pattern is absolutely one that is used and
                    >> useful, so it is worth taking the time to understand it.
                    >>
                    >> I try to make these examples as simple as possible, while sticking to
                    >> the original intent of the pattern. In the GoF on page 334 - 335 the
                    >> UML shows anObjectStructu re calling the concrete element (which I call
                    >> the visitee) with accept(Visitor) , the concrete element then calls the
                    >> visitor, which in turn calls a method back in the concrete element.[/color]
                    >
                    >Exactly; what's the point in calling Visitee->accept(Visitor ), whose
                    >only job is to call Visitor->visit(this)? If ObjectStructure has a
                    >reference to both Visitor and Visitee, why doesn't it just call
                    >Visitor->visit(Visitee) ? This would make for a simpler, more intuitive
                    >arrangement.
                    >[/color]

                    I'm not clear if you object to the Visitor pattern as it is generally
                    accepted in the OO world, or only to my example of it.

                    The accept mechanism allows the objectStructure (my testVisitor) to
                    create the Visitee (eg BookVisitee) and Visitor (eg
                    PlainDescriptio nVisitor) that is appropriate for whatever
                    obectStructure needs. The objectStructure then uses
                    Visitee->visit(Visito r) to simultaneously register the appropriate
                    Visitor with the Visitee, and allow the Visitee to call the approprite
                    function for and with itself in the Visitor. Then the function in the
                    Visitor having been passed a Visitee knows what functions in the
                    Visitee it needs.

                    The objectStructure merely chooses the pieces to be used, the pieces
                    then in turn run the show. Sure, objectStructure could control
                    everything and not let the pieces specify anything. In the Visitor
                    pattern the Structure calls the Visitee calls the Visitor calls the
                    Visitor. Of course, there are often many useful variations of any
                    pattern, and a derivative might be just the thing for a given need.
                    I'm just trying to show the pattern in it's most classical established
                    form.

                    (I know my written descriptions of these patterns aren't the greatest.
                    This is why I merely provide examples and don't have much tutorial
                    verbiage on www.fluffycat.com/SDCMSv2/)
                    [color=blue][color=green]
                    >> A useful example of the visitor pattern could show the visitor being
                    >> able to create HTML or XML output for the same concrete element. I
                    >> didn't do this because it would "muddy the waters" of the example with
                    >> whatever overhead I'd need to add to produce the HTML and XML.[/color]
                    >
                    >But even that wouldn't require the double dispatch, e.g.:
                    >
                    >$book = new Book();
                    >$HTMLThing = new HTMLThing();
                    >$XMLThing = new XMLThing();
                    >
                    >$HTMLThing->display($book) ;
                    >$XMLThing->display($book) ;
                    >
                    >[/color]

                    Well, I'd have a more robust example in general, which could show the
                    pattern in a more useful light, but also more complex. I think that
                    the simplicity of testVisitor could be undermining my example to some
                    degree by making some things simpler and yet also perhaps pointless.
                    [color=blue]
                    >P.S.: Please don't top-post...[/color]

                    k, while I think "top-posting" can make the response part of the
                    message clearer, if it is against established comp.lang.php standards
                    I'll certainly stop. I'm all about following standards.

                    Comment

                    • FluffyCat

                      #11
                      Re: the Visitor Design Pattern

                      On 30 Nov 2005 10:57:01 -0800, "Chung Leong"
                      <chernyshevsky@ hotmail.com> wrote:
                      [color=blue]
                      >Oli Filth wrote:[color=green]
                      >>
                      >> $book = new Book();
                      >> PlainDescriptio nVisitor::descr ibe($book);[/color]
                      >
                      >Passing input data to a block of reusable code--that's just normal
                      >programming. What this world coming to when programmers feel they can't
                      >do something if it's not called a design pattern? The end is near, I
                      >fear.[/color]


                      It's hard to say just how much OO will catch on in PHP. If it does,
                      patterns are certain to follow. If you find yourself working in a
                      team with pattern fans, your best defense against using patterns is to
                      understand them so you can defend your reasons for not using them.

                      Comment

                      • Oli Filth

                        #12
                        Re: the Visitor Design Pattern

                        FluffyCat said the following on 30/11/2005 19:48:[color=blue]
                        > On 30 Nov 2005 08:35:22 -0800, "Oli Filth" <catch@olifilth .co.uk>
                        > wrote:[color=green]
                        >>
                        >>Exactly; what's the point in calling Visitee->accept(Visitor ), whose
                        >>only job is to call Visitor->visit(this)? If ObjectStructure has a
                        >>reference to both Visitor and Visitee, why doesn't it just call
                        >>Visitor->visit(Visitee) ? This would make for a simpler, more intuitive
                        >>arrangement .
                        >>[/color]
                        >
                        > I'm not clear if you object to the Visitor pattern as it is generally
                        > accepted in the OO world, or only to my example of it.[/color]


                        I think I'd have to say that I "object" (a rather strong term, though ;)
                        ) to your example, because it doesn't demonstrate any benefits that
                        arise from the double dispatch.

                        If you were treating $book and $software polymorphically within
                        testVisitor.php , then this would be a viable demonstration of the use of
                        double dispatch.

                        Alternatively, if your accept() methods were doing more than just
                        calling the visit() methods (i.e. actually performing some sort of
                        private operations inside the Visitee classes) then this would also
                        demonstrate some kind of "point" to an arrangement like this.

                        But as it stands, in testVisitor.php you're merely substituting a call
                        to $plainVisitor->visitBook($boo k) with a call to
                        $book->accept($plainV isitor), which is only likely to make people think
                        "Well, what's the point in that?".




                        --
                        Oli

                        Comment

                        • FluffyCat

                          #13
                          Re: the Visitor Design Pattern

                          Ok, excellent stuff to think about. The problem with doing these
                          examples is that there is a huge difference between getting your code
                          to run and having a good example of a pattern.

                          I did add a function to my testVisitor that will take in any Visitee
                          and Visitor and call $visitee->accept($visito r), and so adds a bit
                          more polymorphism to the mix.

                          I'm still not convinced this is necessary for a viable Visitor
                          example, but if it helps to make things seem at all clearer I'm
                          totally into it.

                          I would have preferred, as was suggested, to give the Visitor some
                          special access to Visitor. However, I don't see how to do this with
                          PHP. In C++ you can set up friend (?) classes. In Java you can have
                          package level access. As is stated in GoF, "the pattern often forces
                          you to provide public operations to access the element's internal
                          state, which may compromise it's encapsulation". I guess you could
                          say that Visitor Pattern is a way to add a new operation to a class
                          with out altering the class - but without the advantage of having any
                          special class access.

                          Comment

                          Working...