The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

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.

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?

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.

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).

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

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

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".

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!

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...

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 .

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.

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.