搜索
首页后端开发php教程深入浅析PHP中的组合模式

深入浅析PHP中的组合模式

Jul 15, 2021 pm 07:30 PM
php组合模式设计模式

在之前的文章《一文了解PHP中的享元模式》中我们介绍了PHP中的享元模式,下面本篇文章带大家了解一下PHP设计模式中的组合模式。

深入浅析PHP中的组合模式

互联网公司流行扁平化管理,也就是管理层级尽量少于或者不超过三层,作为一个底层的码农,你的CEO和你的职级也就相差3层以内。但是很多传统企业,则会有非常深的层级关系,从数据结构看,这种按职能进行分组的组织架构非常像一颗树。而我们今天介绍的组合模式的作用就和这个企业组织架构层级的模式非常类似。

Gof类图及解释

GoF定义:将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性

GoF类图

1.png

代码实现

abstract class Component
{
    protected $name;

    public function __construct($name){
        $this->name = $name;
    }
    
    abstract public function Operation(int $depth);

    abstract public function Add(Component $component);

    abstract public function Remove(Component $component);
}

抽象出来的组合节点声明,在适当情况下实现所有类的公共接口的缺省行为,是所有子节点的父类。

class Composite extends Component
{
    private $componentList;

    public function Operation($depth)
    {
        echo str_repeat('-', $depth) . $this->name . PHP_EOL;
        foreach ($this->componentList as $component) {
            $component->Operation($depth + 2);
        }
    }

    public function Add(Component $component)
    {
        $this->componentList[] = $component;
    }

    public function Remove(Component $component)
    {
        $position = 0;
        foreach ($this->componentList as $child) {
            ++$position;
            if ($child == $component) {
                array_splice($this->componentList, ($position), 1);
            }
        }
    }

    public function GetChild(int $i)
    {
        return $this->componentList[$i];
    }
}

具体的节点实现类,保存下级节点的引用,定义实际的节点行为。

class Leaf extends Component
{
    public function Add(Component $c)
    {
        echo 'Cannot add to a leaf' . PHP_EOL;
    }
    public function Remove(Component $c)
    {
        echo 'Cannot remove from a leaf' . PHP_EOL;
    }
    public function Operation(int $depth)
    {
        echo str_repeat('-', $depth) . $this->name . PHP_EOL;
    }
}

叶子节点,没有子节点的最终节点。

  • 从来代码来看,完全就是一颗树的实现
  • 所有的子节点和叶子节点都可以处理数据,但叶子节点为终点
  • 你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑使用组合模式
  • 用户不用关心到底是处理一个叶节点还是处理一个组合组件 ,也就用不着为定义组合而写一些选择判断语句了
  • 组合模式可以让客户一致性地使用组合结构和单个对象

接着文章最开头的例子来说,在我们的组织架构中,一项任务下达到最底的人员时,会经历多个层级。我还是比较喜欢传统一起的企业管理方式。通常是一名总监对应多个主管,一名主管对应多位经理,一位经理对应多位组长,一名组长对应多名员工。当一个通知下发时,每一层级的工作人员都要做出回应,并将通知继续下发到下属员工那里,同时从下属哪里获得反馈。这样,我们就不知不觉地在实践中完成了一次组合模式的应用。突然感觉自己棒棒哒,感觉人生已经到达了巅峰!!

完整代码:https://github.com/zhangyue0503/designpatterns-php/blob/master/14.composite/source/composite.php

实例

短信短信,这个功能我们可以是翻来覆去的用了。这次也不例外。这一回我们的网站后台的功能是要针对不同分站和不同来源的用户进行短信的发送。在这里,我们依然只关注短信发送这件事儿,我们希望给你不同渠道角色但包含统一行为的用户,你来进行发送就行了,这样的功能似乎并不难吧!

短信发送类图

2.png

完整源码:https://github.com/zhangyue0503/designpatterns-php/blob/master/14.composite/source/composite-msg.php

<?php

abstract class Role
{
    protected $userRoleList;
    protected $name;
    public function __construct(String $name)
    {
        $this->name = $name;
    }

    abstract public function Add(Role $role);

    abstract public function Remove(Role $role);

    abstract public function SendMessage();
}

class RoleManger extends Role
{
    public function Add(Role $role)
    {
        $this->userRoleList[] = $role;
    }

    public function Remove(Role $role)
    {
        $position = 0;
        foreach ($this->userRoleList as $n) {
            ++$position;
            if ($n == $role) {
                array_splice($this->userRoleList, ($position), 1);
            }
        }
    }

    public function SendMessage()
    {
        echo "开始发送用户角色:" . $this->name . &#39;下的所有用户短信&#39;, PHP_EOL;
        foreach ($this->userRoleList as $role) {
            $role->SendMessage();
        }
    }
}

class Team extends Role
{

    public function Add(Role $role)
    {
        echo "小组用户不能添加下级了!", PHP_EOL;
    }

    public function Remove(Role $role)
    {
        echo "小组用户没有下级可以删除!", PHP_EOL;
    }

    public function SendMessage()
    {
        echo "小组用户角色:" . $this->name . &#39;的短信已发送!&#39;, PHP_EOL;
    }
}

// root用户
$root = new RoleManger(&#39;网站用户&#39;);
$root->add(new Team(&#39;主站用户&#39;));
$root->SendMessage();

// 社交版块
$root2 = new RoleManger(&#39;社交版块&#39;);
$managerA = new RoleManger(&#39;论坛用户&#39;);
$managerA->add(new Team(&#39;北京论坛用户&#39;));
$managerA->add(new Team(&#39;上海论坛用户&#39;));

$managerB = new RoleManger(&#39;sns用户&#39;);
$managerB->add(new Team(&#39;北京sns用户&#39;));
$managerB->add(new Team(&#39;上海sns用户&#39;));

$root2->add($managerA);
$root2->add($managerB);
$root2->SendMessage();

说明

  • 当我要发送论坛版块的用户时,我可以自由地添加各地方站的叶子节点来控制发送对象
  • 你可以把整个$root2的发送看作是一个整体,不同的版块和地区看成是部分
  • 这个组合可以一直向下延伸,直到深度的叶子节点结束,这个度当然是由自己来把控,很清晰明了

原文地址:https://juejin.cn/post/6844903967407734792

作者:硬核项目经理

推荐学习:《PHP视频教程

以上是深入浅析PHP中的组合模式的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:掘金--硬核项目经理。如有侵权,请联系admin@php.cn删除
您如何在PHP中创建和使用接口?您如何在PHP中创建和使用接口?Apr 30, 2025 pm 03:40 PM

本文解释了如何创建,实施和使用PHP中的接口,重点关注其对代码组织和可维护性的好处。

crypt()和password_hash()有什么区别?crypt()和password_hash()有什么区别?Apr 30, 2025 pm 03:39 PM

本文讨论了PHP中的crypt()和password_hash()之间的差异,以进行密码哈希,重点介绍其实施,安全性和对现代Web应用程序的适用性。

如何防止PHP中的跨站点脚本(XSS)?如何防止PHP中的跨站点脚本(XSS)?Apr 30, 2025 pm 03:38 PM

文章讨论了通过输入验证,输出编码以及使用OWASP ESAPI和HTML净化器之类的工具来防止PHP中的跨站点脚本(XSS)。

PHP中的自动加载是什么?PHP中的自动加载是什么?Apr 30, 2025 pm 03:37 PM

自动加载PHP会在需要时自动加载类文件,从而通过减少内存使用和增强代码组织来提高性能。最佳实践包括使用PSR-4和有效组织代码。

什么是PHP流?什么是PHP流?Apr 30, 2025 pm 03:36 PM

PHP流通过一致的API统一处理文件,网络插座和压缩格式等资源的处理,从而提高复杂性并增强代码灵活性和效率。

可以使用PHP上传的文件的最大大小是多少?可以使用PHP上传的文件的最大大小是多少?Apr 30, 2025 pm 03:35 PM

本文讨论了在PHP中管理文件上传大小的管理,重点是2MB的默认限制以及如何通过修改PHP.INI设置来增加它。

PHP中的无效类型是什么?PHP中的无效类型是什么?Apr 30, 2025 pm 03:34 PM

本文讨论了PHP 7.1中引入的PHP中的无效类型,允许变量或参数为指定类型或NULL。它突出显示了诸如提高可读性,类型安全性和明确意图的好处,并解释了如何声明

unset()和unlink()函数之间有什么区别?unset()和unlink()函数之间有什么区别?Apr 30, 2025 pm 03:33 PM

本文讨论了unset()和unlink()功能在编程中的差异,重点关注其目的和用例。 unset()从内存中删除变量,而unlink()从文件系统中删除文件。两者都对效率至关重要

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具