设计模式之组合模式,golang,php实现

程序员卷不动了 2023-03-18 PM 175℃ 0条

组合模式是一种结构型设计模式,它将对象组合成树形结构来表示“整体-部分”的层次关系,使得用户对单个对象和组合对象的访问具有一致性。

组合模式由以下几个角色组成:

  1. 组件(Component):组合中的所有对象都要实现的接口或抽象类,用于定义公共行为并管理所有子组件。
  2. 叶子(Leaf):组合中的叶子节点,它不包含任何子组件。
  3. 容器(Composite):组合中的容器节点,它包含一个或多个子组件,子组件可以是叶子节点或者其他容器节点。

使用组合模式,我们可以将对象组合成树形结构,从而可以方便地进行操作和管理。例如,在图形界面设计中,我们可以将“窗口”、“框架”、“按钮”等控件组合成为一个整体窗口,并进行统一的操作和管理。在一些游戏开发中,我们可以将“人物”、“武器”、“装备”等组件组合成为一个整体,在游戏中进行统一的控制和管理。

golang实现

//组件接口
type Component interface {
    render()
}

//容器组件
type Composite struct {
    children []Component //子组件
}

//添加子组件
func (c *Composite) add(component Component) {
    c.children = append(c.children, component)
}

//移除子组件
func (c *Composite) remove(component Component) {
    for i, child := range c.children {
        if child == component {
            c.children = append(c.children[:i], c.children[i+1:]...)
            break
        }
    }
}

//渲染当前组件及子组件
func (c *Composite) render() {
    fmt.Println("<ul>")
    for _, child := range c.children {
        fmt.Print("<li>")
        child.render()
        fmt.Println("</li>")
    }
    fmt.Println("</ul>")
}

//叶子组件
type Leaf struct {
    name string //组件名称
}

//渲染当前组件
func (l *Leaf) render() {
    fmt.Println(l.name)
}

//测试代码
func main() {
    root := &Composite{} //根容器
    root.add(&Leaf{name: "叶子1"}) //添加一个叶子节点
    root.add(&Leaf{name: "叶子2"}) //添加一个叶子节点

    branch1 := &Composite{} //分支1
    branch1.add(&Leaf{name: "叶子3"}) //添加一个叶子节点
    branch1.add(&Leaf{name: "叶子4"}) //添加一个叶子节点

    branch2 := &Composite{} //分支2
    branch2.add(&Leaf{name: "叶子5"}) //添加一个叶子节点

    root.add(branch1) //将分支1添加到根容器中
    root.add(branch2) //将分支2添加到根容器中

    root.render() //渲染整个组合体
}

php实现

//组件接口
interface Component {
    public function render($depth);
}

//容器组件
class Composite implements Component {
    private $children = array(); //子组件

    //添加子组件
    public function add(Component $component) {
        array_push($this->children, $component);
    }

    //移除子组件
    public function remove(Component $component) {
        $key = array_search($component, $this->children, true);
        if ($key !== false) {
            unset($this->children[$key]);
        }
    }

    //渲染当前组件及子组件
    public function render($depth) {
        echo str_repeat("-", $depth) . "容器组件\n";
        foreach ($this->children as $child) {
            $child->render($depth + 1);
        }
    }
}

//叶子组件
class Leaf implements Component {
    //渲染当前组件
    public function render($depth) {
        echo str_repeat("-", $depth) . "叶子组件\n";
    }
}

//测试代码
$root = new Composite(); //根容器
$root->add(new Leaf()); //添加一个叶子节点

$branch1 = new Composite(); //分支1
$branch1->add(new Leaf()); //添加一个叶子节点
$branch1->add(new Leaf()); //添加一个叶子节点

$branch2 = new Composite(); //分支2
$branch2->add(new Leaf()); //添加一个叶子节点

$root->add($branch1); //将分支1添加到根容器中
$root->add($branch2); //将分支2添加到根容器中

$root->render(0); //渲染整个组合体

定义了一个组件接口Component,其中定义了一个公共的render方法,用于渲染组件。然后,我们定义了一个容器组件Composite和一个叶子组件Leaf,它们实现了Component接口中的render方法。在容器组件中,我们使用一个数组来存储子组件,并通过add和remove方法来添加和移除子组件。在叶子组件中,我们只需要实现render方法,不需要存储任何子组件。

首先创建了一个根容器$root,并通过add方法向其中添加了一个叶子节点和两个容器分支$branch1和$branch2。然后,我们在$branch1和$branch2中分别添加了两个叶子节点,并最终通过调用$root的render方法,将整个组合体渲染出来。

标签: 设计模式

非特殊说明,本博所有文章均为博主原创。

评论啦~