php设计模式之
组合模式
首先,组合模式属于结构型模式,那么什么叫组合模式呢?用组合模式有什么要求呢?使用场景是什么呢?
定义:将对象组合成树形结构以表示“
部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
看定义很难理解,对组合模式还是不能有一个很好的理解~~~~
我们先来根据实例来慢慢理解什么是组合模式吧:
模式中主要包含哪些
角色呢?
1.
Component 是组合中的对象声明接口,在适当的情况下,
实现所有类共有接口的默认行为。声明一个接口用于
访问和管理Component子部件。
2.
Leaf在组合中表示
叶子结点对象,
叶子结点没有子结点。
3.
Composite定义有枝节点行为,
用来存储子部件,在Component接口中实现与子部件有关操作,如增加(
add)和删除(
remove)等。
网络配图
1 类的实现
代码实例
# 声明抽象接口类Component
abstract class Component
{
protected $id;
protected $name;
public function __construct($id,$name)
{
$this->id = $id;
$this->name = $name;
}
abstract public function add(Component $c); # 抽象add方法
abstract public function remove(Component $c); # 抽象remove方法
abstract public function show($depth); # 抽象show方法
}
# 定义具体支节点类,并实现接口中的方法
class Composite extends Component
{
private $children = array(); # 声明空数组
public function add(Component $c)
{
$this->children[$c->id] = $c;
}
public function remove(Component $c)
{
unset($this->children[$c->id]);
}
public function show($depth)
{
$str = str_pad('', $depth , "_");
echo "{$str} {$this->name}<br />";
foreach($this->children as $c)
{
$c->show($depth+5);
}
}
# 声明具体叶子节点,实现接口中的方法
class Leaf extends Component
{
private $children = array();
public function add(Component $c)
{
echo "can not add to a leaf\r\n";
}
public function remove(Component $c)
{
echo "can not remove to a leaf\r\n";
}
public function show($depth)
{
$str = str_pad('', $depth , "_");
echo "{$str} {$this->name}<br />";
}
}
# 客户端调用
class Client
{
public static function main()
{
$root = new Composite(1,'树主干');
$root->add(new Leaf(2,'树叶 2'));
$root->add(new Leaf(3,'树叶 3'));
$com1 = new Composite(4,'树枝干');
$com1->add(new Leaf(5,'树枝干 树叶 1'));
$com1->add(new Leaf(6,'树枝干 树叶 2'));
$root->add($com1);
$root->show(2);
}
}
Client::main();
#输出结果
__ 树主干
_______ 树叶 2
_______ 树叶 3
_______ 树枝干
____________ 树枝干 树叶 1
____________ 树枝干 树叶 2
2 总结
总结以下组合模式的特点:
必须存在
不可分割基本元素;
组合后的
物体任然可以被组合。
举个通俗的例子,原子是化学反应的基本微粒,它在化学反应中不可分割。现在有 C(碳)、H(氢)、O(氧)、N(氮)4种原子,它们可以随机组合成无数种分子,可以是蛋白质,也可以是脂肪,蛋白质和脂肪就是组合。由蛋白质和脂肪又可以一起被组合成肉、大豆等等。
3 缺点
由于组合模式的灵活性,很多人喜欢不假思索的使用组合类。事实上,组合类存在着“过于灵活”、“开销大”的缺陷。我们试想一下,一个元素或组合在整个系统中可能被调用非常多次,但一旦某个元素或组合在系统中的一个节点出现问题,我们将很难排查到那个节点。
再试想一下,若是系统中的某个元素是一条查询数据库的sql语句,而且这条sql语句的开销有些大,一旦它被组合到整个系统的每一个角落,运行系统造成的结果将是灾难性的。