У меня есть следующая структура для использования Принцип Открытого Закрытия
class Payment{
//this is not a model class
// according to OC principle this class should not focus on the implementation
private $paymentInterface;
public function __construct(PaymentInterface $paymentInterface)
{
$this->paymentInterface = $paymentInterface;
}
//so store method does not know which implementation it will get
public function store($request,$id)
{
return $this->paymentInterface->store($request,$id);
}
}
Интерфейс
interface PaymentInterface{
public function store($request,$id = null);
}
Класс обслуживания платежей, содержащий реализацию
class PaymentService implements PaymentInterface{
public function store($request,$id = null){
//payment store logic is here
}
}
Контроллер
class PaymentsController extends Controller{
protected $payment;
public function __construct()
{
$this->payment = new Payment(new PaymentService);
}
public function storePayment(PaymentRequest $request, $id)
{
try {
$response = $this->payment->store($request,$id);
return redirect()->route($this->route.'.index')->with($response['status'],$response['message']);
} catch (\Exception $e) {
return $this->vendorDashboard($e);
}
}
}
Мой вопрос:
Правильный ли подход Open-Close-Principle ?
Используя приведенный выше код, я могу сказать контроллеру, что могу использовать класс PaymentService для реализации.
$payment = new Payment(new PaymentService);
return $payment->store($request,$id);
Если позже я захочу произвести оплату другим способом, например, произвести оплату через счет, тогда я смогу создать новый контроллер, написать новую реализацию в новом классе, например. InvoicePaymentService и указать классу платежей использовать InvoicePaymentService в качестве реализации
$payment = new Payment(new InvoicePaymentService);
return $payment->store($request,$id);
OR
$payment = new Payment(new PayPalPaymentService);
return $payment->store($request,$id);
OR
$payment = new Payment(new AliPayPaymentService);
return $payment->store($request,$id);
Я знаю, что могу связать интерфейс с классом через поставщика услуг, но если я захочу реализовать другую реализацию оплаты, я не смогу изменить класс, верно?
Если я делаю это неправильно, пожалуйста, дайте мне знать.