繁体   English   中英

根据参数选择接口实现

[英]Select interface implementation according to parameter

根据传递的参数选择接口实现的正确方法是什么?

让我们有以下代码:

interface PaymentProcessor {
  public function process(Order $order): void;
}

class CardPayment implements PaymentProcessor {}
class BankTransfer implements PaymentProcessor {}
class OrderService {
  public function __construct( // Load payment processors from DI
    private CardPayment $cardPayment,
    private BankTransfer $bankTransfer,
  ) {}

  // This is what is not clear to me
  private function getPaymentProcessor(string $paymentMethod): PaymentProcessor
  {
    return match ($paymentMethod) {
      'card' => $this->cardPayment,
      'bank' => $this->bankTransfer,
    }
  }

  public function payOrder(Order $order): void
  {
    $processor = $this->getPaymentProcessor($order->getPaymentMethod());
    $processor->process($order);
  }
}

我不清楚的是如何通过付款方式名称获取 PaymentProcessor。

我会使用上面的代码,可能提取到一些“工厂”。 但根据PHP - Using Interfaces, Strategy Pattern and Optional Method Parameters的回答,我可能打破了打开/关闭原则。 那么正确的方法应该是什么?

做到这一点的正确方法可能是策略模式和依赖注入的组合。

参考答案中发布的解决方案是正确的,但缺少一个重要的点 - 诀窍是所有映射都可以通过依赖注入完成。

所以你可以拥有

interface PaymentStrategy {
  public function process(): void;
}

class CardPayment implements PaymentStrategy {
  public function process(): void;
}

class BankTransfer implements PaymentStrategy {
  public function process(): void;
}

class PaymentService {

  private PaymentStrategy $strategy;

  /** @var array<string, PaymentStrategy> $processors */
  public function __construct(private array $processors) {
  }

  public function setStrategy(string $paymentMethod): void {

    if (!array_key_exists($paymentMethod, $this->processors)) {
          throw new \InvalidArgumentException('Processor not found');
    }

    $this->strategy = $this->processors[$paymentMethod];
  }

  public function process(): void {
    $this->strategy->process();
  }
}

因此,您需要做的就是说服您的 DI 容器为您提供所有 PaymentStrategy 实现。 理想情况下采用 paymentMethodName - 策略格式。 或者,您可以向接口和类添加一些函数,返回它的支付方式名称 - 然后运行 ​​foreach - if - return。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM