Learning patterns... Decorator
Learning patterns... Decorator
am 28.09.2007 02:04:55 von Shion
Hi
I'm trying to learn patterns, which I hope to use in my PHP code,
although I'm finding it hard to get any real impression of how patterns
fit in properly, I've done the following test code for Decorator pattern
and want to know:
a) is it correct, this is decorator pattern?
b) how would i use this in practice with a database, eg. how would i
store the 'attributes' in tables, and how would the 'pattern' be used in
conjunction?
Any hints, tips, pointers to examples would be appreciated:
interface IProduct {
public function getName();
public function cost();
}
class CProduct implements IProduct {
private $_name = 'Product';
public function getName() {
return $this->_name;
}
public function cost() {
return 10.99;
}
}
class CWhiteProduct implements IProduct {
private $Product = null;
public function __construct( $product ) {
$this->Product = $product;
}
public function getName() {
return 'White ' . $this->Product->getName();
}
public function cost() {
return $this->Product->cost() + 1.50;
}
}
class CLargeProduct implements IProduct {
private $Product = null;
public function __construct ( $product ) {
$this->Product = $product;
}
public function getName() {
return 'Large ' . $this->Product->getName();
}
public function cost() {
return $this->Product->cost() + 3.00;
}
}
$product = new CProduct();
echo "
A product is {$product->cost()}
";
$largeproduct = new CLargeProduct( $product );
echo "A large product is {$largeproduct->cost()}
";
$whiteproduct = new CWhiteProduct( $product );
echo "A white product is {$whiteproduct->cost()}
";
$largewhiteproduct = new CLargeProduct( $whiteproduct );
echo "A {$largewhiteproduct->getName()} product is
{$largewhiteproduct->cost()}
";
?>
Re: Learning patterns... Decorator
am 28.09.2007 10:03:05 von Willem Bogaerts
> I'm trying to learn patterns, which I hope to use in my PHP code,
> although I'm finding it hard to get any real impression of how patterns
> fit in properly, I've done the following test code for Decorator pattern
> and want to know:
>
> a) is it correct, this is decorator pattern?
> b) how would i use this in practice with a database, eg. how would i
> store the 'attributes' in tables, and how would the 'pattern' be used in
> conjunction?
>
> Any hints, tips, pointers to examples would be appreciated:
The GOF book ("Design Patterns") is quite clear, I think.
A decorator is a class that adds functionality at runtime. Functionality
you could add to your objects in that way are things like spread
payment, discount conditions, etc. The point of the pattern is that you
can add responsibility to specific objects instead of whole classes. It
is an alternative to subclassing (your example was subclassing).
Best regards,
--
Willem Bogaerts
Application smith
Kratz B.V.
http://www.kratz.nl/
Re: Learning patterns... Decorator
am 28.09.2007 10:06:44 von luiheidsgoeroe
On Fri, 28 Sep 2007 10:03:05 +0200, Willem Bogaerts
wrote:
>> I'm trying to learn patterns, which I hope to use in my PHP code,
>> although I'm finding it hard to get any real impression of how patterns
>> fit in properly, I've done the following test code for Decorator pattern
>> and want to know:
>>
>> a) is it correct, this is decorator pattern?
>> b) how would i use this in practice with a database, eg. how would i
>> store the 'attributes' in tables, and how would the 'pattern' be used in
>> conjunction?
>>
>> Any hints, tips, pointers to examples would be appreciated:
> The GOF book ("Design Patterns") is quite clear, I think.
>
>
>
> A decorator is a class that adds functionality at runtime. Functionality
> you could add to your objects in that way are things like spread
> payment, discount conditions, etc. The point of the pattern is that you
> can add responsibility to specific objects instead of whole classes. It
> is an alternative to subclassing (your example was subclassing).
Yup, and Matt Zandstra has a pretty handy real decorator pattern example
in PHP in his book ('PHP 5 Objects, Patterns, and Practice' I believe).
--
Rik Wasmus
Re: Learning patterns... Decorator
am 28.09.2007 10:24:49 von Scott Wertz
Rik Wasmus wrote:
> On Fri, 28 Sep 2007 10:03:05 +0200, Willem Bogaerts
> wrote:
>
>>> I'm trying to learn patterns, which I hope to use in my PHP code,
>>> although I'm finding it hard to get any real impression of how patterns
>>> fit in properly, I've done the following test code for Decorator pattern
>>> and want to know:
>>>
>>> a) is it correct, this is decorator pattern?
>>> b) how would i use this in practice with a database, eg. how would i
>>> store the 'attributes' in tables, and how would the 'pattern' be used in
>>> conjunction?
>>>
>>> Any hints, tips, pointers to examples would be appreciated:
>> The GOF book ("Design Patterns") is quite clear, I think.
>>
>>
>>
>> A decorator is a class that adds functionality at runtime. Functionality
>> you could add to your objects in that way are things like spread
>> payment, discount conditions, etc. The point of the pattern is that you
>> can add responsibility to specific objects instead of whole classes. It
>> is an alternative to subclassing (your example was subclassing).
>
> Yup, and Matt Zandstra has a pretty handy real decorator pattern example
> in PHP in his book ('PHP 5 Objects, Patterns, and Practice' I believe).
>
Are you sure I was subclassing? I thought I would have to use
'extends' to subclass.
I'm creating a new class that implemented same interface and passing
a base class in the constructor, so that is sub-classing?
I thought subclassing would be like:
class WhiteProduct extends Product {
... blah
... blah
}
I thought maybe I could have a CLargeProduct that got it's values from
a database somehow so it was pretty 'generic' and it's values applied
at run-time based on the db content? And the cost() function wraps
around or 'decorates' the base passed through the constructor???
You're probably right, I'm just trying to get a better understanding as
OOP isn't my scene but I would like it to be.
I'm probably very confused ;)
Re: Learning patterns... Decorator
am 28.09.2007 11:11:54 von Willem Bogaerts
> Are you sure I was subclassing? I thought I would have to use
> 'extends' to subclass.
An interface is a purely abstract class. The syntax is different, but
you are still subclassing a (very) generic thing.
> I thought maybe I could have a CLargeProduct that got it's values from
> a database somehow so it was pretty 'generic' and it's values applied
> at run-time based on the db content? And the cost() function wraps
> around or 'decorates' the base passed through the constructor???
The GOF book speaks about "adding responsibility dynamically". The
CLargeProduct class does not add anything dynamically ("at runtime") and
the responsibility is to hand out a value. I don't think a product class
should even be aware of the existence of a database.
Best regards,
--
Willem Bogaerts
Application smith
Kratz B.V.
http://www.kratz.nl/
Re: Learning patterns... Decorator
am 28.09.2007 11:23:20 von Scott Wertz
Willem Bogaerts wrote:
>> Are you sure I was subclassing? I thought I would have to use
>> 'extends' to subclass.
>
> An interface is a purely abstract class. The syntax is different, but
> you are still subclassing a (very) generic thing.
yes, i was reading that 'programming to an interface' really means an
interface or abstract class.
> The GOF book speaks about "adding responsibility dynamically". The
> CLargeProduct class does not add anything dynamically ("at runtime") and
> the responsibility is to hand out a value. I don't think a product class
> should even be aware of the existence of a database.
I wasn't thinking of putting any database login in the decorator itself,
rather this would be done separately and i wouldn't specifically have
such a thing as CWhiteProduct, rather it would be CColourDecorator that
would apply the 'adjusted' cost for the painting job.
I actually found this article now:
http://www.devshed.com/c/a/PHP/Working-with-MySQL-Result-Set s-and-the-Decorator-Pattern-in-PHP/
I think I see what you mean, this does use 'extends' but doesn't add any
new methods and uses same parent calling technique, so is
decorat/subclass a very subtle difference, ie. if you add a new method
not in the parent, it then basically becomes sub-classing?
The thing I'm trying to get to really is how the database data should be
structured and how the actual PHP code would utilise 'attribute' values
such as 'white' and how the code would be structured in the PHP to then
'decorate' my product to find it's real value.
eg. website may have 'Coat' product, might have drop-down 'White',
'Furry', in the db white may cost 1.00 more, if you want it furry, might
be an extra 2.00
what is an object orientated approaching to extracting and processing
this against a base 'product' object??
normally you'd be using switch and if's and things to do things if 'some
attribute' is returned in a dataset, but i want to practice getting rid
of big switch/if type structures.
Re: Learning patterns... Decorator
am 28.09.2007 14:02:24 von Willem Bogaerts
> I think I see what you mean, this does use 'extends' but doesn't add any
> new methods and uses same parent calling technique, so is
> decorat/subclass a very subtle difference, ie. if you add a new method
> not in the parent, it then basically becomes sub-classing?
It is the parent's responsibility to provide a cost. Hence the cost()
method. _HOW_ that cost is determined is an internal responsibility
(which may be met by delegating actions to other classes like
databases). All your subclasses have therefore the same responsibility:
provide a cost. Your subclasses "specialize" in the way this
responsibility is met.
The point of a decorator is that you may need to add responsibility to
an existing instance, so after you have given it a class. This is
impossible to do using subclasses.
> The thing I'm trying to get to really is how the database data should be
> structured and how the actual PHP code would utilise 'attribute' values
> such as 'white' and how the code would be structured in the PHP to then
> 'decorate' my product to find it's real value.
>
> eg. website may have 'Coat' product, might have drop-down 'White',
> 'Furry', in the db white may cost 1.00 more, if you want it furry, might
> be an extra 2.00
There are many ways to do that. Some people incorporate all the details
in the product name, some people use categories, versions, etc. You can
then either calculate the price at runtime with the given versions or
have price entries for all possibilities. I would suggest the latter,
because not all combinations thinkable are necessary deliverable.
Best regards
--
Willem Bogaerts
Application smith
Kratz B.V.
http://www.kratz.nl/
Re: Learning patterns... Decorator
am 28.09.2007 14:54:40 von Scott Wertz
Willem Bogaerts wrote:
> There are many ways to do that. Some people incorporate all the details
> in the product name, some people use categories, versions, etc. You can
> then either calculate the price at runtime with the given versions or
> have price entries for all possibilities. I would suggest the latter,
> because not all combinations thinkable are necessary deliverable.
>
> Best regards
Thanks Willem, I'll have to have a further play with classes/patterns
and look for more examples. The point is, I'm trying to justify using
them to myself over functional programming, at the moment I try building
class based projects and most of the time they just end up being more
confusing, taking longer and not really adding much benefit.
But obviously, I'm doing them wrong, but have no peer to show me what I
should be doing :-(
Cheers.
Re: Learning patterns... Decorator
am 28.09.2007 15:21:26 von Willem Bogaerts
> Thanks Willem, I'll have to have a further play with classes/patterns
> and look for more examples. The point is, I'm trying to justify using
> them to myself over functional programming, at the moment I try building
> class based projects and most of the time they just end up being more
> confusing, taking longer and not really adding much benefit.
One word of advice: patterns are not holy. Don't try to force your code
into a pattern. Even if an existing pattern would be appropriate, you
might choose the wrong one. Read about patterns and see _why_ they are
useful. You may very well come up with a number of patterns of your own.
Some programming languages even create a need for them.
For me, patterns emerge from my code. And as my code is not that unique,
many patterns are recognizable from textbooks as well. Reading about
patterns helps you to identify them if they emerge. But if they don't
emerge, no problem.
And do not be afraid to change things later. No program is perfect and
even if it were today, it wouldn't be tomorrow. If I may suggest a good
read, read "refactoring" by Martin Fowler. It features a nice "let's put
a class statement around this" program and it shows how to morph it into
a real object-oriented one.
Good luck,
--
Willem Bogaerts
Application smith
Kratz B.V.
http://www.kratz.nl/
Re: Learning patterns... Decorator
am 28.09.2007 17:43:03 von Scott Wertz
Thanks Willem! Going to be a long journey :-)
Willem Bogaerts wrote:
>> Thanks Willem, I'll have to have a further play with classes/patterns
>> and look for more examples. The point is, I'm trying to justify using
>> them to myself over functional programming, at the moment I try building
>> class based projects and most of the time they just end up being more
>> confusing, taking longer and not really adding much benefit.
>
> One word of advice: patterns are not holy. Don't try to force your code
> into a pattern. Even if an existing pattern would be appropriate, you
> might choose the wrong one. Read about patterns and see _why_ they are
> useful. You may very well come up with a number of patterns of your own.
> Some programming languages even create a need for them.
> For me, patterns emerge from my code. And as my code is not that unique,
> many patterns are recognizable from textbooks as well. Reading about
> patterns helps you to identify them if they emerge. But if they don't
> emerge, no problem.
>
> And do not be afraid to change things later. No program is perfect and
> even if it were today, it wouldn't be tomorrow. If I may suggest a good
> read, read "refactoring" by Martin Fowler. It features a nice "let's put
> a class statement around this" program and it shows how to morph it into
> a real object-oriented one.
>
> Good luck,