PHP设计模式—组合模式
发布人:shili8
发布时间:2022-12-03 03:34
阅读次数:24
?
定义:
组合模式(composite):将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。当你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一的使用组合结构中的所有对象时,就应该考虑用组合模式了。
?
实现方式:
1、透明方式:叶节点和枝节点对于外界没有什么区别,它们具备完全一致的行为接口,问题则是叶节点会有冗余方法。
2、安全方式:叶节点中的冗余代码不实现,问题则是由于不够透明,所以叶节点和枝节点将不具有相同的接口,客户端的调用需要做相应的判断,带来了不便。
?
代码实例:
一、透明方式实现:
// 1、抽象类component.php
/**
* 包含叶节点和枝节点方法的抽象类
* class component
*/
abstract class component
{
/**
* @var
*/
protected $name;
/**
* component constructor.
* @param $name
*/
public function __construct($name)
{
$this->name = $name;
}
/**
* 添加叶节点或枝节点
* @param component $component
* @return mixed
*/
abstract public function add(component $component);
/**
* @param $depth
* @return mixed
*/
abstract public function display($depth);
}
// 2、枝节点composite.php
/**
* 枝节点
* class composite
*/
class composite extends component
{
/**
* @var array
*/
protected $children = [];
/**
* @param component $component
* @return mixed|void
*/
public function add(component $component)
{
// todo: implement add() method.
$this->children[] = $component;
}
public function display($depth)
{
// todo: implement display() method.
$namestr = str_repeat('-', $depth) . $this->name . '<br>';
foreach ($this->children as $component) {
$namestr .= $component->display($depth + 2);
}
return $namestr;
}
}
// 3、叶节点leaf.php
/**
* 叶节点
* class leaf
*/
class leaf extends component
{
/**
* 叶节点不需要添加子节点,但为了保持叶节点和枝节点一致,代码冗余,透明方式
* @param component $component
* @return mixed|string
*/
public function add(component $component)
{
// todo: implement add() method.
return '叶节点不能添加子节点' . '<br>';
}
public function display($depth)
{
// todo: implement display() method.
return str_repeat('-', $depth) . $this->name . '<br>';
}
}
调用:
// 生成树根root,根上长出两叶leafa和leafb
$root = new composite("root");
$root->add(new leaf("leaf a"));
$root->add(new leaf("leaf b"));
// 根上长出分支 compositex,分支上也有两叶leafxa和leafxb
$comp = new composite("composite x");
$comp->add(new leaf("leaf xa"));
$comp->add(new leaf("leaf xb"));
$root->add($comp);
// 在compositex分支上再长出分支compositexy,分支上也有两叶leafxya和leafxyb
$comp2 = new composite("composite xy");
$comp2->add(new leaf("leaf xya"));
$comp2->add(new leaf("leaf xyb"));
$comp->add($comp2);
echo $root->display(2);
结果:
--root ----leaf a ----leaf b ----composite x ------leaf xa ------leaf xb ------composite xy --------leaf xya --------leaf xyb
?
二、安全方式实现:
// 1、抽象类component.php
/**
* 包含叶节点和枝节点方法的抽象类
* class component
*/
abstract class component
{
/**
* @var
*/
protected $name;
/**
* component constructor.
* @param $name
*/
public function __construct($name)
{
$this->name = $name;
}
/**
* @param $depth
* @return mixed
*/
abstract public function display($depth);
}
// 2、枝节点composite.php
/**
* 枝节点
* class composite
*/
class composite extends component
{
/**
* @var array
*/
protected $children = [];
/**
* @param component $component
* @return mixed|void
*/
public function add(component $component)
{
// todo: implement add() method.
$this->children[] = $component;
}
public function display($depth)
{
// todo: implement display() method.
$namestr = str_repeat('-', $depth) . $this->name . '<br>';
foreach ($this->children as $component) {
$namestr .= $component->display($depth + 2);
}
return $namestr;
}
}
// 3、叶节点leaf.php
/**
* 叶节点
* class leaf
*/
class leaf extends component
{
public function display($depth)
{
// todo: implement display() method.
return str_repeat('-', $depth) . $this->name . '<br>';
}
}
调用:
// 生成树根root,根上长出两叶leafa和leafb
$root = new composite("root");
$root->add(new leaf("leaf a"));
$root->add(new leaf("leaf b"));
// 根上长出分支 compositex,分支上也有两叶leafxa和leafxb
$comp = new composite("composite x");
$comp->add(new leaf("leaf xa"));
$comp->add(new leaf("leaf xb"));
$root->add($comp);
// 在compositex分支上再长出分支compositexy,分支上也有两叶leafxya和leafxyb
$comp2 = new composite("composite xy");
$comp2->add(new leaf("leaf xya"));
$comp2->add(new leaf("leaf xyb"));
$comp->add($comp2);
echo $root->display(2);
结果:
--root ----leaf a ----leaf b ----composite x ------leaf xa ------leaf xb ------composite xy --------leaf xya --------leaf xyb
?

