1

我正在设计一个具有通用代码库的应用程序,但它的某些部分非常特定于某些购物车。随着设计用于容纳的推车数量的增长,我发现自己添加到主类中的方法越多。这使得类相当大和笨重。

如何将事物模块化,以便加载主类的每个特定购物车都有自己的特定方法,只有在购物车的品牌和版本匹配时才会加载这些方法?

例如,假设我现在以这种方式进行设置:

class Thingy {
    public function doStuffMagento16() {...}
    public function getMoreMagento16() {...}
    public function doStuffOpencart15() {...}
    public function getMoreOpencart15() {...}
    public function doStuffPrestashop12() {...}
    public function getMorePrestashop12() {...}
    public function doStuffXcart45() {...}
    public function getMoreXcart45() {...}
}

我如何让它看起来更像这样,这样方法只会重载主类中的默认值:

class Thingy {
    public function doStuff() {...}
    public function getMore() {...}
}

我真的在想我需要创建子类来扩展主类并在调用主界面时自动加载它们,但我想在我尝试之前确保这确实是最有效且易于维护的选项....或者如果我应该去另一个方向。

4

2 回答 2

1

这需要适配器模式;您将特定的购物车界面调整为通用界面。

简单的例子:

/* 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 );

您可以更改实际的实现细节,但这应该会给您一个大致的概念。例如,您很有可能最终为部分或所有原始购物车以及它实现了外观模式,因为您可能希望将对一个原始实现的多个方法调用包装到适配器接口的单个​​方法中。

于 2013-02-05T03:20:51.053 回答
0

创建一个基类,其中包含您所知道的所有购物车通用的所有内容:

class Cart {

    function __construct(){

       $this->id = 1234;
       $this->item = 'basic_item';

    }

}

然后将该类扩展为另一个类:

class anotherCart extends Cart {

    function __construct(){

       $this->item = 'another_basic_item';

    }

}

在这个伪示例中,$this->id变量在Cart和之间是通用的anotherCart,但会随着变化而anotherCart得到特殊处理。$this->item

以这个概念为基础,添加额外的功能和条件,它应该可以帮助您简化即使是最抽象的概念的使用。

于 2013-02-05T03:01:09.947 回答