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

I have some PHP code that connects to shopping cart API (SOAP) endpoints. This is not to one central server, but rather to any number of user's specific endpoint URLs.

Right now I have several different classes that all create their own connection to the users API.

E.G.,

CartProduct.php -> updateProduct() (creates api connection)

CartCategory.php -> updateCategory() (creates api connection)

I was thinking of using a Singleton to share the remote connection, but after reading through questions on SO, and some blogs, apparently everyone hates Singleton.

In my case I don't think a connection pool makes sense. I'm connecting to a remote user's website, so I don't just want to open 5 connections and potentially slow down their website. I think in this case I really want to share ONE connection between this call to the application. I think in the case of a DB, a connection pool makes sense, but not for remote user APIs. Now theoretically, I guess we should think about what happens if the user tries to run updateProduct and updateCategory at the same time... will that break the system?

Is there a design pattern that makes sense here to open a connection which several different classes can share??

I have no idea if this pattern has a name

In my humble opinion, the connection pool would actually make sense. Only you should not initialize all the connections right off. Instead use lazy initialization:

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];
    }

}

This class can would be used like this:

$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);

This way both instance will be able to initialize SOAP connection, but if Foo initialized connection named "ipsum", then Bar instance will get from pool the already initialized SOAP client.

Disclaimer:
This code was not tested. It was written directly in the SO post editor using some copy-paste from older post of mine. This particular syntax also will require PHP 5.4+, therefore you might need to adapt it for running in older PHP 5.* versions.