SitePoint Sponsor |
|
User Tag List
Results 1 to 20 of 20
Thread: Iterator with inheritance?
-
Nov 28, 2004, 17:48 #1
- 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?
-
Nov 29, 2004, 04:07 #2
- Join Date
- Jul 2004
- Location
- Gerodieville Central, UK
- Posts
- 446
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Atealtha
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 {...}
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.
-
Nov 29, 2004, 10:48 #3
- 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?
-
Nov 29, 2004, 11:03 #4
- 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?
-
Nov 29, 2004, 13:30 #5
- 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()));
-
Nov 29, 2004, 14:01 #6
- 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
-
Nov 29, 2004, 16:40 #7
- Join Date
- Nov 2001
- Location
- Bath, UK
- Posts
- 2,498
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by ghurtado
PHP Code:class Pizza {
function setTopping(){...}
}
interface Topping {
function __construct(Topping $yumYum) ;
}
The construct function might look like this:
PHP Code:function __construct(Topping $yumYum) {
$this->decorates = $yumYum;
}
DouglasHello World
-
Nov 29, 2004, 17:38 #8
- 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)
-
Nov 29, 2004, 18:06 #9
- 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
DouglasHello World
-
Nov 30, 2004, 07:45 #10
- Join Date
- Jul 2004
- Location
- Gerodieville Central, UK
- Posts
- 446
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by ghurtado
-
Nov 30, 2004, 08:09 #11
- Join Date
- Jul 2004
- Location
- Gerodieville Central, UK
- Posts
- 446
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by DougBTX
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
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..
Hopefully this clears up all the misunderstanding caused by my laziness to proof read my posts :-P
-
Nov 30, 2004, 14:17 #12
- 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
-
Nov 30, 2004, 14:38 #13
Originally Posted by Brenden Vickery
personally i would never use a decorator for such a problem..
cheers
Sike
-
Nov 30, 2004, 14:43 #14
- 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?
-
Nov 30, 2004, 15:14 #15
Originally Posted by Brenden Vickery
cheers
Sike
ps. brendan what happened to your blog? tired of publishing stuff ?
-
Nov 30, 2004, 15:34 #16
- Join Date
- Nov 2001
- Location
- Bath, UK
- Posts
- 2,498
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by sike
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 anywayNoone ever said to use just one pattern at a time!
DouglasHello World
-
Nov 30, 2004, 16:52 #17
- 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());
}
}
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.
-
Nov 30, 2004, 17:20 #18
Originally Posted by Brenden Vickery
on the other side i try my best to keep my object model as flat as possible...
Originally Posted by Brenden Vickery
cheers
Sike
-
Nov 30, 2004, 19:02 #19
- Join Date
- Nov 2001
- Location
- Bath, UK
- Posts
- 2,498
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Brenden Vickery
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();
}
}
PHP Code:// bad
function testWithHammer(Concrete $object) {
if ($object->isHard()) {
return true;
}
}
PHP Code:// good
function testWithHammer(SupportsIsHard $object) {
if ($object->isHard()) {
return true;
}
}
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,
DouglasHello World
-
Nov 30, 2004, 20:05 #20
- Join Date
- May 2003
- Location
- Calgary, Alberta, Canada
- Posts
- 275
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by DougBTX
Originally Posted by DougBTX
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