关于后端:结构型设计模式组合对象树-Composite

4次阅读

共计 2333 个字符,预计需要花费 6 分钟才能阅读完成。

简介

组合模式又叫对象树,将对象依照树形构造串起来,呈现出部分和整体雷同的个性。

树中每个节点都由两局部组成,首先节点有本人的业务数据,其次节点内能够含有子节点汇合。

比方盒子中能够放物品,也能够放其余小盒子,小盒子里又能够放物品和其余更小的盒子。

当计算盒子的物品价格时,只须要将盒子里自身的物品价格,加上小盒子里所有物品价格即可,递归解决。

角色

  • 形象节点 Component

    定义一个节点的根底办法,如外部增加子节点等

  • 具体节点之叶子节点 Leaf

    叶子节点没有子节点

  • 具体节点之非叶子节点 Composite/Container

    非叶子节点,可增加子节点

或者也能够不辨别是否是叶子节点,都视为节点即可

类图

图中显示,Leaf 和 Composite 都实现 Component 接口。

Composite 可增加或删除子节点,execute 则指派调用子节点的 execute 办法。

Leaf 的 execute 是真正执行逻辑的中央

代码

<?php

abstract class Component
{
    protected $parent;

    public function setParent(Component $parent)
    {$this->parent = $parent;}

    public function getParent(): Component
    {return $this->parent;}

    public function add(Component $component): void { }

    public function remove(Component $component): void { }

    public function isComposite(): bool
    {return false;}

    abstract public function operation(): string;}

class Leaf extends Component
{public function operation(): string
    {return "Leaf";}
}

class Composite extends Component
{
    protected $children;

    public function __construct()
    {$this->children = new \SplObjectStorage();
    }

    public function add(Component $component): void
    {$this->children->attach($component);
        $component->setParent($this);
    }

    public function remove(Component $component): void
    {$this->children->detach($component);
        $component->setParent(null);
    }

    public function isComposite(): bool
    {return true;}

    public function operation(): string
    {$results = [];
        foreach ($this->children as $child) {$results[] = $child->operation();}

        return "Branch(" . implode("+", $results) . ")";
    }
}

function clientCode(Component $component)
{echo "RESULT:" . $component->operation();
}

// 只有一个叶子节点
$simple = new Leaf();
echo "Client: I've got a simple component:\n";
clientCode($simple);

echo "\n";

// 构建一个 tree
$tree = new Composite();
$branch1 = new Composite();
$branch1->add(new Leaf());
$branch1->add(new Leaf());
$branch2 = new Composite();
$branch2->add(new Leaf());
$tree->add($branch1);
$tree->add($branch2);
echo "Client: Now I've got a composite tree:\n";
clientCode($tree);

// 合并两个 tree
function clientCode2(Component $component1, Component $component2)
{if ($component1->isComposite()) {$component1->add($component2);
    }
    echo "RESULT:" . $component1->operation();}

echo "\n";
echo "Client: I don't need to check the components classes even when managing the tree:\n";
clientCode2($tree, $simple);

output:

Client: I've got a simple component:
RESULT: Leaf
Client: Now I've got a composite tree:
RESULT: Branch(Branch(Leaf+Leaf)+Branch(Leaf))
Client: I don't need to check the components classes even when managing the tree:
RESULT: Branch(Branch(Leaf+Leaf)+Branch(Leaf)+Leaf)

本文由 mdnice 多平台公布

正文完
 0