feat : Composite file
This commit is contained in:
24
app/Controller/Test/CompositeController.php
Normal file
24
app/Controller/Test/CompositeController.php
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
89
app/Service/Test/Composite/File/DirectoryComponent.php
Normal file
89
app/Service/Test/Composite/File/DirectoryComponent.php
Normal 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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
65
app/Service/Test/Composite/File/FileComponent.php
Normal file
65
app/Service/Test/Composite/File/FileComponent.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
40
app/Service/Test/Composite/FileService.php
Normal file
40
app/Service/Test/Composite/FileService.php
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"friendsofphp/php-cs-fixer": "^3.0",
|
"friendsofphp/php-cs-fixer": "^3.0",
|
||||||
"hyperf/devtool": "~3.1.0",
|
"hyperf/devtool": "^3.1",
|
||||||
"hyperf/testing": "~3.1.0",
|
"hyperf/testing": "~3.1.0",
|
||||||
"mockery/mockery": "^1.0",
|
"mockery/mockery": "^1.0",
|
||||||
"phpstan/phpstan": "^1.0",
|
"phpstan/phpstan": "^1.0",
|
||||||
|
|||||||
2
composer.lock
generated
2
composer.lock
generated
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "03d201d24ea04aa8cfada8967ab9b056",
|
"content-hash": "1eb424bacaafd82bad0495cac0fff0de",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "carbonphp/carbon-doctrine-types",
|
"name": "carbonphp/carbon-doctrine-types",
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ declare(strict_types=1);
|
|||||||
* @contact group@hyperf.io
|
* @contact group@hyperf.io
|
||||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use function Hyperf\Support\env;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'generator' => [
|
'generator' => [
|
||||||
'amqp' => [
|
'amqp' => [
|
||||||
@@ -41,4 +44,10 @@ return [
|
|||||||
'namespace' => 'App\\Processes',
|
'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
43
document/composite.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
|
||||||
|
### 组合模式 (Composite Pattern) 详解
|
||||||
|
|
||||||
|
> 组合模式是一种结构型设计模式,它允许你将对象组合成树形结构来表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
|
||||||
|
|
||||||
|
#### 核心概念
|
||||||
|
组合模式包含以下几个关键组件:
|
||||||
|
|
||||||
|
#### 结构
|
||||||
|
- Component(抽象构件): 定义组合中所有对象的通用接口,可以是抽象类或接口
|
||||||
|
- Leaf(叶子构件): 表示组合中的叶子节点对象,没有子节点
|
||||||
|
- Composite(容器构件): 定义有子部件的部件行为,存储子部件,并在Component接口中实现与子部件相关的操作
|
||||||
|
|
||||||
|
#### 应用场景
|
||||||
|
|
||||||
|
组合模式适用于以下情况:
|
||||||
|
|
||||||
|
- 需要表示对象的"部分-整体"层次结构
|
||||||
|
- 希望用户忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象
|
||||||
|
- 处理树形结构数据
|
||||||
|
|
||||||
|
#### 优缺点
|
||||||
|
|
||||||
|
##### 优点
|
||||||
|
- 简化客户端代码:客户端可以一致地处理单个对象和组合对象
|
||||||
|
- 易于新增组件类型:新增组件类型时不需要修改现有代码,符合开闭原则
|
||||||
|
- 灵活的结构:可以创建复杂的树形结构,且结构可以动态变化
|
||||||
|
|
||||||
|
##### 缺点
|
||||||
|
- 设计复杂:需要正确区分叶子节点和树枝节点,增加了系统的复杂性
|
||||||
|
- 类型检查:有时需要在运行时检查对象的类型,增加了运行时的开销
|
||||||
|
|
||||||
|
##### 实际应用
|
||||||
|
|
||||||
|
组合模式在以下场景中常见:
|
||||||
|
|
||||||
|
- 文件系统(文件和文件夹)
|
||||||
|
- GUI组件(窗口包含面板,面板包含按钮等)
|
||||||
|
- 组织结构(公司包含部门,部门包含员工)
|
||||||
|
- 菜单系统(菜单包含子菜单和菜单项)
|
||||||
|
|
||||||
|
组合模式通过树形结构组织对象,使得客户端可以统一处理简单元素和复杂元素,大大提高了系统的灵活性和可扩展性。
|
||||||
@@ -56,3 +56,8 @@ Content-Type: application/x-www-form-urlencoded
|
|||||||
### Bridge pay test
|
### Bridge pay test
|
||||||
GET {{host}}/bridge/test/pay
|
GET {{host}}/bridge/test/pay
|
||||||
Content-Type: application/x-www-form-urlencoded
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
|
||||||
|
### Composite pay test
|
||||||
|
GET {{host}}/composite/test/file
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
Reference in New Issue
Block a user