用于管理与远程API的连接的设计模式

时间:2013-08-01 16:06:02

标签: php api oop design-patterns singleton

我有一些连接到购物车API(SOAP)端点的PHP代码。这不是针对一个中央服务器,而是针对任意数量的用户的特定端点URL。

现在我有几个不同的类都创建了自己与用户API的连接。

E.G。,

  

CartProduct.php - > updateProduct()(创建api连接)

     

CartCategory.php - > updateCategory()(创建api连接)

我正在考虑使用 Singleton 来共享远程连接,但在阅读了有关SO和一些博客的问题之后,显然每个人都讨厌Singleton。

就我而言,我认为连接池没有意义。我正在连接到远程用户的网站,所以我不只是想打开5个连接并且可能会减慢他们的网站速度。我想在这种情况下我真的想在这个应用程序调用之间共享一个连接。我认为在数据库的情况下,连接池是有意义的,但不适用于远程用户API。从理论上讲,我想我们应该考虑如果用户同时尝试运行updateProduct和updateCategory会发生什么......会破坏系统吗?

是否有一种设计模式在这里有意义打开几个不同类可以共享的连接?

1 个答案:

答案 0 :(得分:5)

  

我不知道这个模式是否有名称

以我的拙见,连接池实际上是有意义的。只有你不应该立即初始化所有连接。而是使用延迟初始化:

class LazyPool
{

    private $connections = [];
    private $providers = [];

    public function addProvider($name, callable $provider)
    {
        $this->providers[$name] = $provider;
        return $this;
    }

    public function getConnection($name)
    {
        if (array_key_exists($name, $this->connections) === false)
        {
            $this->connections[$name] = call_user_func($this->providers[$name]);
        }
        return $this->connections[$name];
    }

}

这个类可以像这样使用:

$pool = new LazyPool;

$pool->addProvider('lorem', function() use ($config){
    $instance = new SoapThing($config['wsdl_1']);
    return $instance;
});

$pool->addProvider('ipsum', function() use ($config){
    $instance = new SoapThing($config['i_think_it_was_wsdl']);
    return $instance;
});

$foo = new Foo($pool);
$bar = new Bar($pool);

这样两个实例都可以初始化SOAP连接,但是如果Foo初始化了名为"ipsum"的连接,那么Bar实例将从池中获取已经初始化的SOAP客户端。

  

<子>的声明:
  此代码测试。它是使用我的旧帖子中的一些 copy-paste 直接在SO post编辑器中编写的。这个特殊的语法也需要PHP 5.4+,因此您可能需要调整它以便在较旧的PHP 5. *版本中运行。