Symfony2 服务的外观模式

Mik*_*ikO 5 service facade symfony

Symfony2 新手,我正在构建一个使用外部 API 来获取数据的应用程序。我创建了很多客户端类来从 API 检索和转换每个实体,并将这些类定义为服务 - 例如,我有一个像orFooClient之类的 with 方法,它从 API 返回数据。getAll()getThoseThatInterestMe($me)

现在我想创建一个ApiClientFacade类,它充当所有类前面的接口XxxClient,遵循外观模式- 例如,这个外观类将有一个方法getAllFoo(),而该方法又会调用FooClient::getAll(),依此类推......

我也可以将我的外观类定义为服务,但它有太多的依赖项 - 我有大约 30 个客户端类。另外,据我所知,使用这种方法我每次都会加载所有 30 个依赖项,而大多数时候我只需要一个依赖项......

那么,有更好的方法吗?

Yev*_*Kov 4

使用额外的 ApiClientFactory 将有关“ApiClient 对象的实例化”的责任从 ApiFacade 类中转移(据我所知,这是您最初的想法)。

在一些伪 php 代码中我的想法是:

$api = new ApiFacade(new ApiClientFactory);
$api->sendNotificationAboutUserLogin('username', time());
Run Code Online (Sandbox Code Playgroud)

方法示例:

class ApiFacade {
  private $apiFactory;

  public function __construct(ApiClientFactory $factory)
  {
      $this->apiFactory = $factory;
  }    
  public function sendNotificationAboutUserLogin($username, $timeOfOperation)
    {
      return $this->apiFactory
          ->createApi('User')
          ->post(
              'notifications',
              array('operation' => 'login', 'username' => $username, 'timeOfOperation' => $timeOfOperation)
          );
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您的 Facade 类保持可注入(可测试),但也变得更简单可实例化(您不再需要将所有依赖项传递给它)。

ApiClientFactory 应该如下所示:

class ApiClientFactory {
    private $apiBaseUrl;
    public function __construct($apiBaseUrl)
    {
      $this->apiBaseUrl = $apiBaseUrl;
    }
    public function createApi($apiName)
    {
      switch ($apiName) {
        case 'User': return new \My\UserApi($this->apiBaseUrl);
        default: // throw an exception?
      }
    }
}
Run Code Online (Sandbox Code Playgroud)