2013-08-01 103 views
1

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

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

EG,

CartProduct.php - >的UpdateProduct()(创建API连接)

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

我想用单身人士来分享远程连接,但通过阅读SO和一些博客上的问题后,显然每个人都讨厌Singleton。

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

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

+0

当您“需要”单身人士时,单身人士会很有用,您可以选择何时使用它。否则,为什么不创建一个API连接并分别将其传递给适当的产品或类别的类实例。它不必是一个单例,只需在每个其他实例上使用相同的数据库对象。我不是100%的使用相同的连接,虽然对于多个请求,如果没有完成。 – Moylin

+0

@Moylin,单身人士是有用的,如果你只知道如何编写程序代码,但项目负责人要求你使用类和所有其他奇怪的对象的东西。 –

+0

@tereško - 模式是一种解决方案。有时候你没有问题。对于小型作品而言,它们可以很好并且有效。但我理解这个观点。我自己使用自己的单身人士是因为我在自己的项目上懒惰而使用数据库。但是,由于使用DI,它不一定是单身人士,但你只需调用该类的同一个实例,除非你需要一个新的。 – Moylin

回答

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客户端。

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

+0

可能是“提供者模式”? – Jimbo

+0

感谢您深思熟虑的答案 – bonez