feat : Composite file

This commit is contained in:
2025-09-07 19:36:04 +08:00
parent b106c4a352
commit 714baffaf7
10 changed files with 302 additions and 2 deletions

View File

@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace App\Controller\Test;
use App\Service\Test\Composite\FileService;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface;
#[Controller(prefix: 'composite/test')]
class CompositeController
{
/**
* @return array|null
*/
#[RequestMapping(path: 'file', methods: 'GET')]
public function file()
{
return (new FileService)->handle();
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Interface\Test\Composite;
interface FileSystemComponentInterface
{
/**
* 获取名字
* @return string
*/
public function getName(): string;
/**
* 获取大小
* @return int
*/
public function getSize(): int;
/**
* 显示
* @param string $prefix
* @return void
*/
public function display(string $prefix = ''): void;
}

View File

@@ -0,0 +1,89 @@
<?php
/**
* This service file is part of item.
*
* @author ctexthuang
* @contact ctexthuang@qq.com
* @web_site https://ctexthuang.com
*/
declare(strict_types=1);
namespace App\Service\Test\Composite\File;
use App\Interface\Test\Composite\FileSystemComponentInterface;
class DirectoryComponent implements FileSystemComponentInterface
{
/**
* @var string
*/
private string $name;
/**
* @var array
*/
private array $children = [];
/**
* 构造方法
* @param string $name
*/
public function __construct(string $name)
{
$this->name = $name;
}
/**
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* @return int
*/
public function getSize(): int
{
$size = 0;
foreach ($this->children as $child) {
$size += $child->getSize();
}
return $size;
}
/**
* @param string $prefix
* @return void
*/
public function display(string $prefix = ''): void
{
echo $prefix . ":directory:" . $this->name . '(' . $this->getSize() . 'bytes)' . PHP_EOL;
foreach ($this->children as $child) {
$child->display($prefix ,' ');
}
}
/**
* @param FileSystemComponentInterface $component
* @return void
*/
public function add(FileSystemComponentInterface $component): void
{
$this->children[] = $component;
}
/**
* @param FileSystemComponentInterface $component
* @return void
*/
public function remove(FileSystemComponentInterface $component): void
{
$this->children = array_filter($this->children, function ($c) use ($component) {
return $c !== $component;
});
}
}

View File

@@ -0,0 +1,65 @@
<?php
/**
* This service file is part of item.
*
* @author ctexthuang
* @contact ctexthuang@qq.com
* @web_site https://ctexthuang.com
*/
declare(strict_types=1);
namespace App\Service\Test\Composite\File;
use App\Interface\Test\Composite\FileSystemComponentInterface;
class FileComponent implements FileSystemComponentInterface
{
/**
* 文件名字
* @var string
*/
private string $name;
/**
* 文件大小
* @var int
*/
private int $size;
/**
* 构造方法
* @param string $name
* @param int $size
*/
public function __construct(string $name, int $size)
{
$this->name = $name;
$this->size = $size;
}
/**
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* @return int
*/
public function getSize(): int
{
return $this->size;
}
/**
* @param string $prefix
* @return void
*/
public function display(string $prefix = ''): void
{
echo $prefix . ":file:" . $this->name . '(' . $this->size . 'bytes)' . PHP_EOL;
}
}

View File

@@ -0,0 +1,40 @@
<?php
/**
* This service file is part of item.
*
* @author ctexthuang
* @contact ctexthuang@qq.com
* @web_site https://ctexthuang.com
*/
declare(strict_types=1);
namespace App\Service\Test\Composite;
use App\Service\Test\Composite\File\DirectoryComponent;
use App\Service\Test\Composite\File\FileComponent;
use App\Service\Test\TestBaseService;
class FileService extends TestBaseService
{
/**
* @return array
*/
public function handle(): array
{
$root = new DirectoryComponent('root');
$documents = new DirectoryComponent('documents');
$images = new DirectoryComponent('images');
$file1 = new FileComponent('readme.md',1024);
$file2 = new FileComponent('report.pdf',2048);
$file3 = new FileComponent('photo.jpg',4096);
$root->add($documents);
$root->add($images);
$documents->add($file1);
$documents->add($file2);
$images->add($file3);
$root->display();
return $this->return->success();
}
}

View File

@@ -36,7 +36,7 @@
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.0",
"hyperf/devtool": "~3.1.0",
"hyperf/devtool": "^3.1",
"hyperf/testing": "~3.1.0",
"mockery/mockery": "^1.0",
"phpstan/phpstan": "^1.0",

2
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "03d201d24ea04aa8cfada8967ab9b056",
"content-hash": "1eb424bacaafd82bad0495cac0fff0de",
"packages": [
{
"name": "carbonphp/carbon-doctrine-types",

View File

@@ -9,6 +9,9 @@ declare(strict_types=1);
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
use function Hyperf\Support\env;
return [
'generator' => [
'amqp' => [
@@ -41,4 +44,10 @@ return [
'namespace' => 'App\\Processes',
],
],
/**
* Supported IDEs: "sublime", "textmate", "cursor", "emacs", "macvim", "phpstorm", "idea",
* "vscode", "vscode-insiders", "vscode-remote", "vscode-insiders-remote",
* "atom", "nova", "netbeans", "xdebug"
*/
'ide' => env('DEVTOOL_IDE', ''),
];

43
document/composite.md Normal file
View File

@@ -0,0 +1,43 @@
### 组合模式 (Composite Pattern) 详解
> 组合模式是一种结构型设计模式,它允许你将对象组合成树形结构来表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
#### 核心概念
组合模式包含以下几个关键组件:
#### 结构
- Component(抽象构件): 定义组合中所有对象的通用接口,可以是抽象类或接口
- Leaf(叶子构件): 表示组合中的叶子节点对象,没有子节点
- Composite(容器构件): 定义有子部件的部件行为存储子部件并在Component接口中实现与子部件相关的操作
#### 应用场景
组合模式适用于以下情况:
- 需要表示对象的"部分-整体"层次结构
- 希望用户忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象
- 处理树形结构数据
#### 优缺点
##### 优点
- 简化客户端代码:客户端可以一致地处理单个对象和组合对象
- 易于新增组件类型:新增组件类型时不需要修改现有代码,符合开闭原则
- 灵活的结构:可以创建复杂的树形结构,且结构可以动态变化
##### 缺点
- 设计复杂:需要正确区分叶子节点和树枝节点,增加了系统的复杂性
- 类型检查:有时需要在运行时检查对象的类型,增加了运行时的开销
##### 实际应用
组合模式在以下场景中常见:
- 文件系统(文件和文件夹)
- GUI组件(窗口包含面板,面板包含按钮等)
- 组织结构(公司包含部门,部门包含员工)
- 菜单系统(菜单包含子菜单和菜单项)
组合模式通过树形结构组织对象,使得客户端可以统一处理简单元素和复杂元素,大大提高了系统的灵活性和可扩展性。

View File

@@ -56,3 +56,8 @@ Content-Type: application/x-www-form-urlencoded
### Bridge pay test
GET {{host}}/bridge/test/pay
Content-Type: application/x-www-form-urlencoded
### Composite pay test
GET {{host}}/composite/test/file
Content-Type: application/x-www-form-urlencoded