PHP应用来自实现相同接口的多个类的代码

时间:2018-10-25 10:03:05

标签: php symfony oop interface

我目前正在实施一个项目,并且对实现同一接口的多个类有疑问。

因此,现在我有多种可应用于订单的折扣类型。因此,我创建了一个带有check()方法的DiscountInterface,它检查折扣是否适用以及应用折扣的apply()方法。

到目前为止,太好了。然后,我在实现DiscountInterface并具有检查和应用此特定折扣的逻辑的类中实现了第一个折扣类型。

在我的控制器中,注入DiscountInterface。收到订单后,我会同时调用check()和apply()方法,并且一切运行正常。

我的问题如下。我实行第二种折扣。实现之后,我将不得不创建一个实现DiscountInterface的新类。但是,当需要在控制器上调用它时,应该怎么做。由于我必须使用不同的类,使用相同的方法。

如果我有一个实现这些方法的类,则下面的代码有效,但是如果我有两个实现这些方法的类,会发生什么?

public function discount(
    Request $request, 
    DiscountInterface $discount, 
    CustomerRepository $customer, 
    ProductRepository $product, 
    ValidatorInterface $validator,
    OrderServiceInterface $orderService
)
{
    $data = json_decode($request->getContent(), true);
    $order = $orderService->convertDataToOrder($data, $customer, $product, $validator);

    if($discount->check($order, $customer)){
        $order = $discount->apply($order);
    }

1 个答案:

答案 0 :(得分:2)

如果您需要检查所有折扣类型,而不是传递实现类,而不是传递DiscountFactory呢?

<?php

use My\Discount\CrapDiscount;
use My\Discount\AwesomeDiscount;

class DiscountFactory
{
    /** @var DiscountInterface[] */
    private $discounts;

    public function __construct()
    {
        $this->discounts = [
            new CrapDiscount(),
            new AwesomeDiscount(),
        ];
    }

    public function getDiscounts(): array
    {
        return $this->discounts;
    }
}

然后您的代码可能如下所示:

public function discount(
    Request $request, 
    DiscountFactory $discountFactory, 
    CustomerRepository $customer, 
    ProductRepository $product, 
    ValidatorInterface $validator,
    OrderServiceInterface $orderService
)
{
    $data = json_decode($request->getContent(), true);
    $order = $orderService->convertDataToOrder($data, $customer, $product, $validator);

    foreach ($discountFactory->getDiscounts() as $discount) {
        if($discount->check($order, $customer)){
            $order = $discount->apply($order);
        }
    }
    // etc