SitePoint Sponsor

User Tag List

Results 1 to 20 of 20
  1. #1
    SitePoint Addict
    Join Date
    Jan 2004
    Location
    New York
    Posts
    254
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Iterator with inheritance?

    What is the main advantage of having an iterator with two seperate classes, passing objects by reference as parameters?

    Is it better to create an iterator with inheritance, rather than the non stop reference using and foreign method calling?

  2. #2
    Resident Java Hater
    Join Date
    Jul 2004
    Location
    Gerodieville Central, UK
    Posts
    446
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Atealtha
    passing objects by reference as parameters?
    I assume that you are refering to the Decorator pattern used by a lot of the SPL Iterator classes.

    it is better to use the Decorator as you can mix and match behaviours from different classes

    Think about about this situation....

    PHP Code:
    class Pizza {
         function 
    __construct(Topping &$yumYum) {...}
    }

    interface 
    Topping {
         function 
    addTopping();
    }

    class 
    Bacon implements Topping {...}
    class 
    Chesse implements Topping {...}
    class 
    Tomato implements Topping {...}
    class 
    Ham implements Topping {...}
    class 
    Chicken implements Topping {...}
    class 
    PineApple implements Topping {...}
    class 
    SpicyCrapThatGivesYouTheRuns implements Topping {...} 
    you have more flexiblity here as you can do something like ...

    new Pizza(new Cheese(new Tomato()));

    OR

    new Pizza(new Cheese(new Bacon(new PineApple())));

    Basically, you can mix and match the toppings you want. With Inheritance, you have to state which you are extending from and therefore you can not mix and match things, unless you get a big class explosion.

  3. #3
    SitePoint Evangelist ghurtado's Avatar
    Join Date
    Sep 2003
    Location
    Wixom, Michigan
    Posts
    591
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think I am missing something in the construct you propose, MiiJaySung, how does the constructor of the Topping class take other toppings as arguments?

  4. #4
    SitePoint Enthusiast
    Join Date
    Jun 2004
    Location
    South Africa
    Posts
    28
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    As i see it, the Pizza class constructor's parameter is of type Topping which all the topping classes (Cheese, Bacon, etc.) implement. Thus, you can pass any class that implements the Topping interface to the Pizza constructor. Am i right?

  5. #5
    SitePoint Evangelist ghurtado's Avatar
    Join Date
    Sep 2003
    Location
    Wixom, Michigan
    Posts
    591
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry, I should have made my question clearer. Yes, I understand that the constructor for the Pizza class takes a Topping object as an argument, what I do not understand is how the Topping class itself can take other toppings as implied by:
    PHP Code:
    new Pizza(new Cheese(new Tomato())); 
    It seems to me that Cheese (a Topping) should be able to accept other toppings (tomato) as an argument in order for this to work, yet I see no constructor for the Topping class that explains how this is handled.

  6. #6
    SitePoint Enthusiast
    Join Date
    Jun 2004
    Location
    South Africa
    Posts
    28
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I would assume that the constructors of the topping classes also have a Topping parameter, thus allowing you to "embed" them within one another

  7. #7
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ghurtado
    yet I see no constructor for the Topping class that explains how this is handled.
    It just looks like a typo to me, the methods are the wrong way around. Should look like this imo:

    PHP Code:
    class Pizza 
         function 
    setTopping(){...} 


    interface 
    Topping 
         function 
    __construct(Topping $yumYum) ; 

    the second is still a little iffy, because it implies that there will be a never ending chain of Toppings, becasue the last one will need to be constructed with a Topping argument too... Where I've done something like this, I've just thrown an exception if the paramater passed in is not the correct type (but simply do nothing if I get null).

    The construct function might look like this:

    PHP Code:
    function __construct(Topping $yumYum) {
      
    $this->decorates $yumYum;

    hth,
    Douglas
    Hello World

  8. #8
    SitePoint Evangelist ghurtado's Avatar
    Join Date
    Sep 2003
    Location
    Wixom, Michigan
    Posts
    591
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks Doug, just the clarification I was looking for (I think)

  9. #9
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I don't believe that the pizza example is any good to be honest, if I was going to model a pizza I would use a collection, not a decorator. Using decorators (as far as I understand the pattern) it is like wrapping classes around a centeral class in a chain. With a collection, you have a generic base class and you add ther classes to the collection. That sounds much more like a pizza to me: you take the pizza base, and you add your toppings on top.

    But then a real pizza is more complex than our simple model. Whenever I make one, I make a base to start off with, then I wrap that base in a layer of tomato paste, then add all the other toppings ontop of the tomato. I doubt that your average application would use only collections or only decorators. If you set up your classes well enough, you could easily decorate things before you add them to a collection. Once you start doing that, it becomes a question of what you want to do with your application code, rather than a theoretical discussion of what the options are. But then the theoretical abstraction might help you apply solutions to your application. Then again it might not. I guess you've got to learn like everyone else

    Douglas
    Hello World

  10. #10
    Resident Java Hater
    Join Date
    Jul 2004
    Location
    Gerodieville Central, UK
    Posts
    446
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ghurtado
    I think I am missing something in the construct you propose, MiiJaySung, how does the constructor of the Topping class take other toppings as arguments?
    This was just mock code to illustrate communication between classes. However if people need some example code for the constructor i will provide it.

  11. #11
    Resident Java Hater
    Join Date
    Jul 2004
    Location
    Gerodieville Central, UK
    Posts
    446
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by DougBTX
    I don't believe that the pizza example is any good to be honest, if I was going to model a pizza I would use a collection,
    I kinda agree here. My example was a little flawed as I didn't have time to think it through. I just used the first thing thaat came to mind. The arguement over whether it is a decorator or a collection that gets iterated over is debatable. Ideally, when you make a pizza you need to place toppings in a set order (for instance tomato paste at bottom, cheese, meat, vegtables, chillies spice and other cack). The decorator's "wrapping" behaviour matches this stack-like behaviour. On the other hand, decorators are very suited to pre / post processing. This is something you wouldn't really consider when you make a Pizza as you just slap the toppings on one after another.

    But then a real pizza is more complex than our simple model. Whenever I make one, I make a base to start off with, then I wrap that base in a layer of tomato paste, then add all the other toppings ontop of the tomato
    Again this is debateable :-P When I make a pizza the model is a a lot more simple. I go to a supermarket, find a ready prepared pizza, and end up burning the crap out of it as I normally forget its in the oven

    the second is still a little iffy, because it implies that there will be a never ending chain of Toppings, becasue the last one will need to be constructed with a Topping argument too..
    I was aware of this flaw as I posted the post. I wasn't too fussed as the idea of the post was to illustrate roughly the communication. I dislike the use of passing NULL as a default value as you can not do class typing in the function signature. Instead a better way is to have a setTopping(Topping &$flavour) method in place of the constrcutor. The method that processes toppings would need to check if the wrapped topping is NULL to determin the top most flavour.

    Hopefully this clears up all the misunderstanding caused by my laziness to proof read my posts :-P

  12. #12
    SitePoint Addict
    Join Date
    May 2003
    Location
    Calgary, Alberta, Canada
    Posts
    275
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I came across a fairly good, in-depth explaination of why composition is sometimes preferable over inheritance.

    http://www.oreilly.com/catalog/hfdes...apter/ch03.pdf

    enjoy

  13. #13
    SitePoint Zealot sike's Avatar
    Join Date
    Oct 2002
    Posts
    174
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Brenden Vickery
    I came across a fairly good, in-depth explaination of why composition is sometimes preferable over inheritance.

    http://www.oreilly.com/catalog/hfdes...apter/ch03.pdf

    enjoy
    hummm, why did they use a decorator? just to show how you can use it?
    personally i would never use a decorator for such a problem..

    cheers
    Sike

  14. #14
    SitePoint Addict
    Join Date
    May 2003
    Location
    Calgary, Alberta, Canada
    Posts
    275
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Interesting, I thought they explained their choice fairly well. What would you do?

  15. #15
    SitePoint Zealot sike's Avatar
    Join Date
    Oct 2002
    Posts
    174
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Brenden Vickery
    Interesting, I thought they explained their choice fairly well. What would you do?
    yeah the explanation is good and entertaining but my first guess would be a simple collection of items (nothing fancy i guess). i really don't see why this won't work. to be honest i don't work with patterns in the first place. they appear while i am refactoring my code (or not (; ). till now i never asked myself "what pattern would solve this problem best".

    cheers
    Sike

    ps. brendan what happened to your blog? tired of publishing stuff ?

  16. #16
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by sike
    to be honest i don't work with patterns in the first place. they appear while i am refactoring my code (or not (; ). till now i never asked myself "what pattern would solve this problem best".
    Often I think "I've seen this problem before", in which case knowing the names of patterns which can help solve that problem can be useful. You can google the name of the pattern to quickly read about other people's experiences with it for example.

    I don't really need to ask the "what pattern" question most of the time: I have a good idea how I'm going to solve my problem anyway Noone ever said to use just one pattern at a time!

    Douglas
    Hello World

  17. #17
    SitePoint Addict
    Join Date
    May 2003
    Location
    Calgary, Alberta, Canada
    Posts
    275
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The reason this thread caught my attention and I was doing a little research on decorators vs inheritance is because of the offered solution to Helge in this thread: http://www.sitepoint.com/forums/showthread.php?t=211839

    I decorated the eclipse iterator with a "DomainObjectIterator". I was wondering what if any benefit this had over inheriting from QueryIterator like this:
    PHP Code:
    class DomainObjectIterator extends QueryIterator {
        function 
    DomainObjectIterator($mapper$recordSet) {
            
    $this->mapper $mapper;
            
    parent::QueryIterator($recordSet);
        }
        function 
    getCurrent() {
            return 
    $this->mapper->load(parent::getCurrent());
        }

    One advantage or disadvantage of using inheritance depending how you look at it is that in php5 with type hints this will work with a type of QueryIterator where the decorated solution wont.

    Using inheritance also means that one less class needs to be instanciated.

    Im undecided on which solution is the "better" solution. Anyone have thoughts on this?

    I stopped blogging for all the usual reasons, too much work, too much golf, too much blah. Ill get back on it and post some stuff soon since you asked .

  18. #18
    SitePoint Zealot sike's Avatar
    Join Date
    Oct 2002
    Posts
    174
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Brenden Vickery
    The reason this thread caught my attention and I was doing a little research on decorators vs inheritance is because of the offered solution to Helge in this thread: http://www.sitepoint.com/forums/showthread.php?t=211839

    I decorated the eclipse iterator with a "DomainObjectIterator". I was wondering what if any benefit this had over inheriting from QueryIterator like this:
    PHP Code:
    class DomainObjectIterator extends QueryIterator {
         function 
    DomainObjectIterator($mapper$recordSet) {
             
    $this->mapper $mapper;
             
    parent::QueryIterator($recordSet);
         }
         function 
    getCurrent() {
             return 
    $this->mapper->load(parent::getCurrent());
         }
     } 
    One advantage or disadvantage of using inheritance depending how you look at it is that in php5 with type hints this will work with a type of QueryIterator where the decorated solution wont.

    Using inheritance also means that one less class needs to be instanciated.

    Im undecided on which solution is the "better" solution. Anyone have thoughts on this?
    i use decorators rarely for the exact same reason : Interfaces and type hints in php5. if i really think a decorator suits best i setup a decorator base class implementing the appropiate interface (mostly to make type hinting work).
    on the other side i try my best to keep my object model as flat as possible...

    Quote Originally Posted by Brenden Vickery
    I stopped blogging for all the usual reasons, too much work, too much golf, too much blah. Ill get back on it and post some stuff soon since you asked .
    hehe, ok. just asked out of interest

    cheers
    Sike

  19. #19
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Brenden Vickery
    One advantage or disadvantage of using inheritance depending how you look at it is that in php5 with type hints this will work with a type of QueryIterator where the decorated solution wont.
    Have you heard of the "Design to an interface, not an implementation" line?

    It seems like it overlaps with the arguments for using decorators, though I'm not quite sure how to put it into words. Will have a go anyway:

    When you decorate something, you keep the interface the same, but you don't directly extend the concrete class you had to start with, you just call its methods from the decorator. Here is some code:

    PHP Code:
    interface SupportsIsHard {
        function 
    isHard();
    }

    class 
    Concrete impliments SupportsIsHard {
        function 
    isHard() {
            return 
    true;
        }
    }

    class 
    Decorator impliments SupportsIsHard {
        function 
    isHard() {
            return !
    $this->wrapped->isHard();
        }

    What you have probably looks like this:
    PHP Code:
    // bad
    function testWithHammer(Concrete $object) {
       if (
    $object->isHard()) {
          return 
    true;
       }

    If you program to the interface, your type hinting should use the interface, not the concrete class.

    PHP Code:
    // good
    function testWithHammer(SupportsIsHard $object) {
       if (
    $object->isHard()) {
          return 
    true;
       }

    Now, testWithHammer will not care whether $object is concrete or decorated, as long as it implements SupportsIsHard.

    I think it all boils down to the "extends is evil" thing, or rather "extends can be inflexible" if you want to get closer to the mark, but it does not sound half as good!

    Later,
    Douglas
    Hello World

  20. #20
    SitePoint Addict
    Join Date
    May 2003
    Location
    Calgary, Alberta, Canada
    Posts
    275
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by DougBTX
    Have you heard of the "Design to an interface, not an implementation" line?

    It seems like it overlaps with the arguments for using decorators, though I'm not quite sure how to put it into words. Will have a go anyway:

    When you decorate something, you keep the interface the same, but you don't directly extend the concrete class you had to start with, you just call its methods from the decorator.
    Quote Originally Posted by DougBTX
    I think it all boils down to the "extends is evil" thing, or rather "extends can be inflexible" if you want to get closer to the mark, but it does not sound half as good!
    Youre right of course, and that is why I was wrong in both the inheritance example and the decorator example. Neither conformed to the same interface as QueryIterator. The return type for getCurrent was changed from an array to an Object.

    Using the QueryIterator example, it is best not to use inheritance so that a DomainObjectIterator can not be used with a QueryIterator type hint.

    This doesnt answer the original question though . My advice would be to use either inheritance or a decorator as long as you keep the interface the same. Dont spend to much time thinking about this sort of thing until you have to, and then refactor to suit your needs.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •