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

bon*_*nez 1 php oop api singleton design-patterns

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

现在我有几个不同的类,它们都创建自己与用户API的连接.

例如,

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

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

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

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

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

ter*_*ško 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];
    }

}
Run Code Online (Sandbox Code Playgroud)

这个类可以像这样使用:

$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);
Run Code Online (Sandbox Code Playgroud)

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

免责声明:
此代码经过测试.它是使用我的旧帖子中的一些复制粘贴直接在SO帖子编辑器中编写的.这个特殊的语法也需要PHP 5.4+,因此您可能需要调整它以便在较旧的PHP 5.*版本中运行.