php - 如何使用同一类使用多个服务
问题描述
我需要一种方法来处理同一个类的多个不同服务。假设我有一个本地数据库,用于存储我的本地帖子。每次我将帖子保存到这个本地数据库时,我也需要发布这些服务。所以他们肯定需要一个适配器模式,这样我就可以总是使用相同的方法。这很清楚,但我不确定如何使主类可互换,以便我可以即时加载所需的平台和服务。
结构可能如下:
App App
Adapters Adapters
ServiceA ServiceB
Post.php Post.php
Category.php Category.php
... ...
通过使用适配器模式中的方法,Post.php
将适应相同的方法sendPost()
和deletePost()
.
现在我将能够使用相同的 sendPost() 方法为每个平台发送帖子。我可以这样做。
$post = Post::create($form_array);
$services = Service::get();
foreach ($services as $service){
$class = '\\App\\Adapters\\'.$service->name.'\\Post';
$service = new $class;
$service->sendPost($post);
}
或者
$post = Post::where('id', 44);
$services = Service::get();
foreach ($services as $service){
$class = '\\App\\Adapters\\'.$service->name.'\\Post';
$service = new $class;
$service->deletePost($post->id);
}
实际上,这种方法有效,但似乎(感觉)不是正确的方法。例如,每次我需要另一个服务而不是 Post 时,我都需要创建另一个实例。
$class = '\\App\\Adapters\\'.$service->name.'\\Category';
$service = new $class;
$service->deletePost($post->id);
我正在寻找更多类似的东西。
$service = new Service('ServiceA');
$service->post->sendPost($post);
$service->category->create($cat);
那么我可以
$post = Post::where('id', 44);
$services = Service::get();
foreach ($services as $service){
$service = new Service($service->name)
$service->post->deletePost($post->id);
}
我知道这不是一个非常详细的表示,但你明白了。我想使用多种服务并能够用我的本地系统实现它。那么什么是正确和最好的方法呢?
解决方案
在将方法添加到当前现有的类时,我不是专家。这个问题一直萦绕在我的脑海中,我一直在研究一个可能不是最干净的解决方案,但我认为你会喜欢它。
最后,这就是我能够访问每个 Post.php 文件中的方法的方式。
public function __construct()
{
$this->service = Service::boot();
}
public function test()
{
$service = Service::getService('ServiceB');
return $service->post->testPost();
}
public function testGlobal()
{
return $this->service->serviceA->post->testPost();
}
public function testAllServices()
{
$service = Service::boot();
return $service->serviceA->post->testPost();
}
为了实现这一点,我没有你原来的服务文件,所以我在 App/Adapters 做了一个
<?php
namespace App\Adapters;
class Service
{
public static function boot() {
$directory = dirname(__DIR__).'/Adapters';
$services = array_diff(scandir($directory), array('..', '.'));
$container = new class {};
foreach($services as $key => $service) {
if (is_dir(dirname(__DIR__).'/Adapters/'.$service)) {
$container->{lcfirst($service)} = new class {};
$directory = dirname(__DIR__).'/Adapters/'.$service;
$classes = array_diff(scandir($directory), array('..', '.'));
foreach($classes as $secondary_key => $class) {
$class = str_replace('.php', '', $class);
$namespace = 'App\Adapters\\'.$service.'\\'.$class;
$container->{lcfirst($service)}->{lcfirst($class)} = new $namespace;
}
}
}
return $container;
}
public static function getService($service) {
$container = new class {};
$directory = dirname(__DIR__).'/Adapters/'.$service;
$classes = array_diff(scandir($directory), array('..', '.'));
foreach($classes as $secondary_key => $class) {
$class = str_replace('.php', '', $class);
$namespace = 'App\Adapters\\'.$service.'\\'.$class;
$container->{lcfirst($class)} = new $namespace;
}
return $container;
}
}
主要目的是扫描适配器中的所有内容,并根据父目录创建实现类的方法。
如果您喜欢,我可以在需要时提供更多解释。
推荐阅读
- c# - Web 参考 C# 的可配置值
- python - 在 python 中,如何为使用打开文件的函数编写单元测试?
- android - 当我们对某些用户进行身份验证时,我们是否需要添加 livedata?
- android - 以线性布局居中 Edittext - Android
- sql - 在oracle plsql中添加n个工作日,包括自定义假期列表
- return - 布尔返回类型混淆
- javascript - 使用 Node Express 从 Apache Ignite 获取数据的问题
- ios - 将CustomView添加到navigationItem后,CustomView总是返回nil
- python - 使用vscode在带有python3.8的venv中“Pylint:无法导入XXX”
- r - Purrr 映射多个模型以将结果存储在数据框中