検証



class Pet{
	public $name = 'none';
	
	public function getName(){
		return $this->name;
	}
	public function bark(){
		return '吠える';
	}
	public function price(){
		return 0;
	}
}

class Cat extends Pet{
	
	public function __construct(){
		$this->name = 'ネコ';
	}
	public function bark(){
		return  'ニャゴー';
	}
	public function price(){
		return 10000;
	}
}

class Dog extends Pet{
	
	public function __construct(){
		$this->name = '犬';
	}
	public function bark(){
		return  'ワンワン';
	}
	public function price(){
		return 10;
	}
}

// デコレータークラス
class Decorator extends Pet{
	protected $pet;
	
	public function __construct(Pet $pet){
		$this->pet = $pet;
	}
	
	public function getName(){
		return $this->pet->getName();
	}
	
	public function bark(){
		return $this->pet->bark();
	}
	
	public function price(){
		return $this->pet->price();
	}
}

class Big extends Decorator{

	public function getName(){
		return '大きい' . $this->pet->getName();
	}
	
	public function price(){
		return $this->pet->price() + 500;
	}
	
}

class Small extends Decorator{

	public function getName(){
		return '小さい' . $this->pet->getName();
	}
	public function price(){
		return $this->pet->price() + 200;
	}
	
}

class Black extends Decorator{

	public function getName(){
		return '黒い' . $this->pet->getName();
	}
	
	public function price(){
		return $this->pet->price() + 50;
	}
	
}

class Bowlingual extends Decorator{

	public function bark(){
		return $this->pet->bark() . '(今日の天気はいかがですか)';
	}
	
}

// 検証

$cat = new Cat();
output($cat);

$bigCat = new Big($cat);
output($bigCat);

$smallCat = new Small($cat);
output($smallCat);

$blackCat = new Bowlingual($smallCat);
output($blackCat);

$blackCat = new Black($smallCat);

$dog = new Dog();
$dog = new Black($dog);
$dog = new Big($dog);
output($dog);

function output(Pet $pet){
	echo $pet->getName() . ' → ' . $pet->bark() . ' → ' .  $pet->price() . '円<br>';
}

出力

ネコ → ニャゴー → 10000円
大きいネコ → ニャゴー → 10500円
小さいネコ → ニャゴー → 10200円
小さいネコ → ニャゴー(今日の天気はいかがですか) → 10200円
大きい黒い犬 → ワンワン → 560円