Door
Leander ---
op 24-03-2011 12:04
gewijzigd op 24-03-2011 12:05
7.818 views
Ik ben bezig om grip te krijgen op Design Patterns. Het lukt niet helemaal, dus vandaar dat ik hier op PHPHulp even een topic aan heb gemaakt. Om het voor me zelf duidelijk te maken, heb ik eerst een kleine omschrijving gemaakt van hoe het Decorator pattern werkt (daar ben ik op dit moment mee bezig).
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.
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?)
Bedankt, maar ik heb al een soortgelijk boek tot m'n beschikking. Ik wou alleen even peilen of ik een beetje op de goede weg zat en het decorator pattern begrijp.
Zit ik dus een beetje op de goede weg? Of begrijp ik het hele patroon verkeerd?
Je bent op de goede weg :) De UML klopt.
Heb even wat PHP toegevoegd voor een uitwerking ;)
index.php:
<?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();
?>
Beverage.class.php
<?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;
}
}
?>
Uitwerking:
Beschrijving : Expresso, Mocha, Sugar
Euro : 2.8
Beschrijving : Expresso
Euro : 2
Had geen zin om alle classes in aparte bestanden te zetten ;)
mmmh, dat is een slordigheidje inderdaad die typefout.
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.