I have a following structure to use Open Close Principle
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
interface PaymentInterface{
public function store($request,$id = null);
}
Payment Service Class containing implementation
class PaymentService implements PaymentInterface{
public function store($request,$id = null){
//payment store logic is here
}
}
Controller
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);
}
}
}
My question is: Is it correct approach to use Open-Close-Principle ? Using above code I can tell controller that I can use PaymentService class for the implementation.
$payment = new Payment(new PaymentService);
return $payment->store($request,$id);
If later I want to make a payment in different way e.g. make a payment through invoice then I can create new controller, write new implementation in new class e.g. InvoicePaymentService and tell Payment class to use InvoicePaymentService as implementation
$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);
I know I can bind Interface with a class through a service provider but if I want to implement a different payment implementation then I will not be able to change the class, right ?
If I am doing it in wrong way please let me know.