我有以下结构来使用打开关闭原则
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
}
}
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);
}
}
}
我的问题是: 使用 Open-Close-Principle 是否正确? 使用上面的代码我可以告诉 Controller 我可以使用 PaymentService 类来实现。
$payment = new Payment(new PaymentService);
return $payment->store($request,$id);
如果稍后我想以不同的方式付款,例如通过发票付款然后我可以创建新的 Controller ,在新类中编写新的实现,例如InvoicePaymentService 并告诉 Payment 类使用 InvoicePaymentService 作为实现
$payment = new Payment(new InvoicePaymentService);
return $payment->store($request,$id);
或
$payment = new Payment(new PayPalPaymentService);
return $payment->store($request,$id);
或
$payment = new Payment(new AliPayPaymentService);
return $payment->store($request,$id);
我知道我可以通过服务提供商将接口(interface)与类绑定(bind),但如果我想实现不同的支付实现,那么我将无法更改类,对吧?
如果我做错了,请告诉我。
最佳答案
这就是服务容器的含义。你应该使用 contextual binding
假设你有一个接口(interface):FooInterface
您有两个具体实现:GoodFoo 和 BadFoo
为了向 Controller (或其他类)注入(inject)不同的实现你必须告诉 laravel。
$this->app->when(GoodController::class)
->needs(FooInterface::class)
->give(function () {
return new GoodFoo();
});
$this->app->when(BadController::class)
->needs(FooInterface::class)
->give(function () {
return new BadFoo();
});
Controller 应该是:
class GoodController extends Controller
{
protected $foo;
public function __construct(FooInterface $foo)
{
$this->foo = $foo;
}
}
class BadController extends Controller
{
protected $foo;
public function __construct(FooInterface $foo)
{
$this->foo = $foo;
}
}
请注意,大多数时候 laravel 提倡糟糕的软件设计原则,并且很难在 laravel 中实践 SOLID 原则。
关于php - LARAVEL:如何使用SOLID原则的Open Close Principle?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55040713/