Design Patterns
Quote:
Het decorator patroon is een ontwerppatroon dat gebruikt wordt om functionaliteiten toe te voegen aan objecten. Dit is beter uit te leggen aan de hand van een UML diagram.
AbcComponent is in dit geval de abstracte klasse die er voor zorgt dat iedereen die deze klasse extends, de functie Operation() moet implementeren. ComponentA en AbcDecorator extenden de hoofdklasse, AbcComponent, om invulling te geven in dit functie.
AbcDecorator heeft dat weer 2 subklasses onder zich die zorgen voor een extra stukje functionaliteit. Het kan zo zijn dat in het ene geval de klasse DecoratorA gebruikt wordt, en in het andere geval DecoratorB. Dit zorgt er dus voor dat er in beide gevallen er iets anders getoond/gedaan wordt.
AbcComponent is in dit geval de abstracte klasse die er voor zorgt dat iedereen die deze klasse extends, de functie Operation() moet implementeren. ComponentA en AbcDecorator extenden de hoofdklasse, AbcComponent, om invulling te geven in dit functie.
AbcDecorator heeft dat weer 2 subklasses onder zich die zorgen voor een extra stukje functionaliteit. Het kan zo zijn dat in het ene geval de klasse DecoratorA gebruikt wordt, en in het andere geval DecoratorB. Dit zorgt er dus voor dat er in beide gevallen er iets anders getoond/gedaan wordt.
Zit ik een beetje op de goede weg, of ben ik nog te oppervlakkig bezig? Ik ben al een hele tijd aan het zoeken en uitspitten, maar ik krijg de link niet helemaal goed.
(Waarom Decorator? Dat is nodig voor wat ik wil gaan maken (ja onderzocht)).
Ik ben ook nog bezig met Abstract Factory. Is het mogelijk om die te combineren met het Decorator pattern (en dat weer gecombineerd met het MVC model?)
Gewijzigd op 24/03/2011 12:05:44 door Leander ---
http://my.safaribooksonline.com/book/software-engineering-and-development/patterns/0596007124
en dan in hoofdstuk 3 wordt decerator uitgelegd ;)
Goed boek: en dan in hoofdstuk 3 wordt decerator uitgelegd ;)
Zit ik dus een beetje op de goede weg? Of begrijp ik het hele patroon verkeerd?
Gewijzigd op 25/03/2011 13:23:45 door Leander ---
Heb even wat PHP toegevoegd voor een uitwerking ;)
index.php:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
include ('Beverage.class.php');
$drink = new Expresso();
$drink = new Mocha($drink);
$drink = new Sugar($drink);
echo 'Beschrijving : ' . $drink->getDescription();
echo '<br>';
echo 'Euro : '. $drink->cost();
echo '<br><br>';
$drink = new Expresso();
echo 'Beschrijving : ' . $drink->getDescription();
echo '<br>';
echo 'Euro : '. $drink->cost();
?>
include ('Beverage.class.php');
$drink = new Expresso();
$drink = new Mocha($drink);
$drink = new Sugar($drink);
echo 'Beschrijving : ' . $drink->getDescription();
echo '<br>';
echo 'Euro : '. $drink->cost();
echo '<br><br>';
$drink = new Expresso();
echo 'Beschrijving : ' . $drink->getDescription();
echo '<br>';
echo 'Euro : '. $drink->cost();
?>
Beverage.class.php
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?php
abstract class Beverage {
public $description = 'unknown';
public function getDescription() {
return $this->description;
}
public abstract function cost();
}
abstract class CondimentDecorator extends Beverage {
public function getDescription() {
parent::getDescription();
}
}
class Expresso extends Beverage {
public function __construct() {
$this->description = 'Expresso';
}
public function cost() {
return 2;
}
}
class Mocha extends CondimentDecorator {
private $beverage;
public function __construct(Beverage $b) {
$this->beverage = $b;
}
public function getDescription() {
return $this->beverage->getDescription() . ', Mocha';
}
public function cost() {
return $this->beverage->cost() + 0.10;
}
}
class Sugar extends CondimentDecorator {
private $beverage;
public function __construct(Beverage $b) {
$this->beverage = $b;
}
public function getDescription() {
return $this->beverage->getDescription() . ', Sugar';
}
public function cost() {
return $this->beverage->cost() + 0.70;
}
}
?>
abstract class Beverage {
public $description = 'unknown';
public function getDescription() {
return $this->description;
}
public abstract function cost();
}
abstract class CondimentDecorator extends Beverage {
public function getDescription() {
parent::getDescription();
}
}
class Expresso extends Beverage {
public function __construct() {
$this->description = 'Expresso';
}
public function cost() {
return 2;
}
}
class Mocha extends CondimentDecorator {
private $beverage;
public function __construct(Beverage $b) {
$this->beverage = $b;
}
public function getDescription() {
return $this->beverage->getDescription() . ', Mocha';
}
public function cost() {
return $this->beverage->cost() + 0.10;
}
}
class Sugar extends CondimentDecorator {
private $beverage;
public function __construct(Beverage $b) {
$this->beverage = $b;
}
public function getDescription() {
return $this->beverage->getDescription() . ', Sugar';
}
public function cost() {
return $this->beverage->cost() + 0.70;
}
}
?>
Uitwerking:
Quote:
Beschrijving : Expresso, Mocha, Sugar
Euro : 2.8
Beschrijving : Expresso
Euro : 2
Euro : 2.8
Beschrijving : Expresso
Euro : 2
Had geen zin om alle classes in aparte bestanden te zetten ;)
Gewijzigd op 25/03/2011 14:21:38 door Remco nvt
Je kan CondimentDecorator ook nog een constructor geven.
Heb je hier toevallig nog een leuk voorbeeld 'in real life' van?
Je kan denken aan een kassa systeem om inderdaad toevoegingen.
De JAVA I/O stream implementation is een decorator pattern.
Of het gebruiken voor je gegevens aan te passen. Dus je string o.i.d.
Voor de rest, bedankt van je PHP voorbeeld code. Helpt zeker wel om het beter te begrijpen. Ik zal het even goed gaan bestuderen.
Sommige gratis php design patterns scripts die je kunt bekijken op de pagina:
http://www.phpkode.com/scripts/category/php-design-patterns/