What is correct way to select interface implementation according to passed parameter?
Let's have following code:
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);
}
}
What is not clear to me is how can I get PaymentProcessor by payment method name.
I would use code above, probably extracted to some "Factory". But according to answer at PHP - Using Interfaces, Strategy Pattern and Optional Method Parameters I am probably breaking open/close principle. Then what should be correct way?
My Answer:
> 'card' => $this->cardPayment,
> 'bank_transfer' => $this->bankTransfer,
> default => throw new \InvalidArgumentException('Invalid payment method'),
> };
> }
In the `getPaymentProcessor` method, you can use a `match` expression to select the appropriate implementation based on the passed parameter `paymentMethod`. This way, you can return the correct implementation of the `PaymentProcessor` interface according to the parameter value.
Rate this post
4 of 5 based on 3844 votesComments