Afr*_*mad 6 php open-closed-principle solid-principles laravel
我有以下结构可以使用开闭原理
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);
}
}
Run Code Online (Sandbox Code Playgroud)
接口
interface PaymentInterface{
public function store($request,$id = null);
}
Run Code Online (Sandbox Code Playgroud)
包含实现的支付服务类
class PaymentService implements PaymentInterface{
public function store($request,$id = null){
//payment store logic is here
}
}
Run Code Online (Sandbox Code Playgroud)
控制者
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是: 使用Open-Close-Principle是否正确?使用上面的代码,我可以告诉控制器可以将PaymentService类用于实现。
$payment = new Payment(new PaymentService);
return $payment->store($request,$id);
Run Code Online (Sandbox Code Playgroud)
如果以后我想以其他方式付款(例如通过发票付款),则可以创建新的控制器,在新类(例如InvoicePaymentService)中编写新的实现,并告诉Payment类使用InvoicePaymentService作为实现
$payment = new Payment(new InvoicePaymentService);
return $payment->store($request,$id);
Run Code Online (Sandbox Code Playgroud)
要么
$payment = new Payment(new PayPalPaymentService);
return $payment->store($request,$id);
Run Code Online (Sandbox Code Playgroud)
要么
$payment = new Payment(new AliPayPaymentService);
return $payment->store($request,$id);
Run Code Online (Sandbox Code Playgroud)
我知道我可以通过服务提供商将Interface绑定到类,但是如果我想实现其他支付方式,那么我将无法更改类,对吗?
如果我做错了方法,请告诉我。
这就是服务容器的代表。您应该使用上下文绑定
假设您有一个接口:FooInterface
您有两个具体的实现:GoodFoo和BadFoo
为了将不同的实现注入到控制器(或其他类)中,必须将其告知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();
});
Run Code Online (Sandbox Code Playgroud)
控制器应该是:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,大多数时候laravel提倡糟糕的软件设计原则,而在laravel中实践SOLID原则却相当困难。
| 归档时间: |
|
| 查看次数: |
291 次 |
| 最近记录: |