如何使用相同的 class 使用多个服务
How to consume multiple services using same class
我需要一种方法来处理具有相同 class 的多个不同服务。假设我有一个本地数据库,其中存储了我的本地 post。每次我将 post 保存到这个本地数据库时,我也需要 post 使用这些服务。所以他们肯定需要一个适配器模式,这样我就可以始终使用相同的方法。这很清楚,但我不确定如何使主要 class 可互换,以便我可以动态加载所需的平台和服务。
结构可能是这样的:
App App
Adapters Adapters
ServiceA ServiceB
Post.php Post.php
Category.php Category.php
... ...
通过在 Post.php
中使用适配器模式方法,将采用相同的方法 sendPost()
和 deletePost()
。
现在我可以使用相同的 sendPost() 方法为每个平台发送 post。我可以这样做。
$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);
}
我知道这不是一个非常详细的表示,但你明白了。我想使用多种服务并能够使用我的本地系统来实现它。那么正确和最好的方法是什么?
在将方法添加到现有 Class 方面,我不是专家。这个问题一直困扰着我,我一直在研究一个可能不是最干净的解决方案,但我认为你会喜欢它。
最后,这就是我能够访问每个 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;
}
}
主要目的是扫描适配器中的所有内容,并根据父目录创建实现 class 的方法。
如果您喜欢,我可以根据需要提供更多解释。
我需要一种方法来处理具有相同 class 的多个不同服务。假设我有一个本地数据库,其中存储了我的本地 post。每次我将 post 保存到这个本地数据库时,我也需要 post 使用这些服务。所以他们肯定需要一个适配器模式,这样我就可以始终使用相同的方法。这很清楚,但我不确定如何使主要 class 可互换,以便我可以动态加载所需的平台和服务。
结构可能是这样的:
App App
Adapters Adapters
ServiceA ServiceB
Post.php Post.php
Category.php Category.php
... ...
通过在 Post.php
中使用适配器模式方法,将采用相同的方法 sendPost()
和 deletePost()
。
现在我可以使用相同的 sendPost() 方法为每个平台发送 post。我可以这样做。
$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);
}
我知道这不是一个非常详细的表示,但你明白了。我想使用多种服务并能够使用我的本地系统来实现它。那么正确和最好的方法是什么?
在将方法添加到现有 Class 方面,我不是专家。这个问题一直困扰着我,我一直在研究一个可能不是最干净的解决方案,但我认为你会喜欢它。
最后,这就是我能够访问每个 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;
}
}
主要目的是扫描适配器中的所有内容,并根据父目录创建实现 class 的方法。
如果您喜欢,我可以根据需要提供更多解释。