2016年3月13日 星期日

php composite + __call

```php class Weapon { protected $name; protected $attack = 0; protected $addions = []; public function __construct($name, $attack, $addions = []) { $this->name = $name; $this->attack = $attack; $this->addions = $addions; } public function setAttack($attack) { $this->attack = $attack; } public function attack() { $attack = $this->attack; foreach ($this->addions as $addion) { $attack += $addion->attack(); } return $attack; } public function __call($method, $parameters) { foreach ($this->addions as $addion) { if (method_exists($addion, $method) === true) { return call_user_func_array([$addion, $method], $parameters); } } die('error'); } } abstract class Addion { protected $attack = 0; public function attack() { return $this->attack; } } class ToxicAddion extends Addion { protected $attack = 15; public function toxic() { echo 'toxic'; } } class LightingAddion extends Addion { protected $attack = 10; public function lighting() { echo 'lighting'; } } $sword = new Weapon('劍', 10, [ new ToxicAddion(), new LightingAddion(), ]); echo $sword->attack(); echo $sword->toxic(); echo $sword->lighting(); // output // 35 // toxic // lighting ```

PHP decorator + __call

``` class Weapon { public function attack() { return 10; } } abstract class Decorator { protected $weapon; public function __construct($weapon) { $this->weapon = $weapon; } abstract public function attack(); public function __call($method, $parameters) { return call_user_func_array([$this->weapon, $method], $parameters); } } class ToxicDecorator extends Decorator { public function attack() { return $this->weapon->attack() + 15; } public function toxic() { echo 'toxic'; } } class LightingDecorator extends Decorator { public function attack() { return $this->weapon->attack() + 5; } public function lighting() { echo 'lighting'; } } $weapon = new Weapon(); $weapon = new ToxicDecorator($weapon); $weapon = new LightingDecorator($weapon); echo $weapon->attack(); echo $weapon->toxic(); echo $weapon->lighting(); // output // 30 // toxic // lighting ```