设计模式(8) Composite模式

 

目的

组合成树形结构的“整体-部分”。

Composite

实现

abstract class MenuComponent 
{
    public $name;  
    public abstract function getName();  
    public abstract function add(MenuComponent $menu);  
    public abstract function remove(MenuComponent $menu);  
    public abstract function getChild($i);  
    public abstract function show();  
}
class MenuItem extends MenuComponent  
{
    public function __construct($name)  
    {  
        $this->name = $name;  
    }  
    public function getName(){  
        return $this->name;  
    }  
    public function add(MenuComponent $menu){  
        return false;  
    }  
    public function remove(MenuComponent $menu){  
        return false;  
    }  
  
    public function getChild($i){  
        return null;  
    }  
    public function show(){  
        echo " |-".$this->getName()."\n";  
    }  
}  
  
class Menu extends MenuComponent  
{  
    public $menuComponents = array();  
    public function __construct($name)  
    {  
        $this->name = $name;  
    }  
  
    public function getName()  
    {  
        return $this->name;  
    }  
  
    public function add(MenuComponent $menu)  
    {  
       $this->menuComponents[] = $menu;  
    }  
  
    public function remove(MenuComponent $menu)  
    {  
        $key = array_search($menu, $this->menuComponents);  
        if($key !== false) unset($this->menuComponents[$key]);  
    }  
  
    public function getChild($i)  
    {  
        if(isset($this->menuComponents[$i])) return $this->menuComponents[$i];  
        return null;  
    }  
  
    public function show()  
    {  
        echo ":" . $this->getName() . "\n";  
        foreach($this->menuComponents as $v){  
            $v->show();  
        }  
    }  
}  
$menu1 = new Menu('文学');  
$menuitem1 = new MenuItem('绘画');  
$menuitem2 = new MenuItem('书法');  
$menuitem3 = new MenuItem('小说');  
$menuitem4 = new MenuItem('雕刻');  
$menu1->add($menuitem1);  
$menu1->add($menuitem2);  
$menu1->add($menuitem3);  
$menu1->add($menuitem4);  
$menu1->show();