这需要适配器模式;您将特定的购物车界面调整为通用界面。
简单的例子:
/* existing cart implementation */
class CartFromVendorX
{
public function addProduct( CartXProduct $product ) {}
}
/* existing cart implementation */
class CartFromVendorY
{
public function pushProduct( CartYProduct $product ) {}
}
/* generic cart interface */
interface CartAdapterInterface
{
public function addItem( $item );
}
class CartAdapterVendorX
implements CartAdapterInterface
{
protected $adaptee;
public function __construct( CartFromVendorX $adaptee )
{
$this->adaptee = $adaptee;
}
public function addItem( $item )
{
/* transfrom generic $item to CartXProduct, for instance */
$this->adaptee->addProduct( $product );
}
}
class CartAdapterVendorY
implements CartAdapterInterface
{
protected $adaptee;
public function __construct( CartFromVendorY $adaptee )
{
$this->adaptee = $adaptee;
}
public function addItem( $item )
{
/* transfrom generic $item to CartYProduct, for instance */
$this->adaptee->pushProduct( $product );
}
}
然后是一个通用的购物车消费客户端:
class CartClient
{
protected $cart;
public function __construct( CartAdapterInterface $cart )
{
$this->cart = $cart;
}
/* rest of implementation that acts on CartAdapterInterface instance */
}
用法:
$cartAdapter = new CartAdapterVendorX( new CartFromVendorX() );
$client = new CartClient( $cartAdapter );
PS:您不一定必须实现适配器,以便将原始实现传递给它们的构造函数。像这样的东西也可以工作:
class CartAdapterVendorX
implements CartAdapterInterface
{
protected $adaptee;
public function __construct()
{
$this->adaptee = new CartFromVendorX();
}
public function addItem( $item )
{
/* perhaps transfrom generic $item first */
$this->adaptee->addProduct( $item );
}
}
然后它的用法将简化为:
$cartAdapter = new CartAdapterVendorX();
$client = new CartClient( $cartAdapter );
您可以更改实际的实现细节,但这应该会给您一个大致的概念。例如,您很有可能最终为部分或所有原始购物车以及它实现了外观模式,因为您可能希望将对一个原始实现的多个方法调用包装到适配器接口的单个方法中。