LARAVEL:如何使用 SOLID 原则的开闭原则?
Posted
技术标签:
【中文标题】LARAVEL:如何使用 SOLID 原则的开闭原则?【英文标题】:LARAVEL: How to use Open Close Principle of SOLID principles? 【发布时间】:2019-03-07 09:50:06 【问题描述】:我有以下结构使用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 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 并告诉 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);
我知道我可以通过服务提供者将接口与类绑定,但如果我想实现不同的支付实现,那么我将无法更改类,对吧?
如果我做错了,请告诉我。
【问题讨论】:
“但是如果我想实现不同的支付实现” - 你的意思是不同的支付类实现吗? 是的。我在问题中提到过。就像我想用 PayPal 或支付宝付款一样 【参考方案1】:这就是服务容器的含义。你应该使用contextual binding
假设你有一个接口: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();
);
控制器应该是:
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 原则相当困难。
【讨论】:
太棒了。这是我在网上找到的 这意味着我们不必编写泛型类。我们可以根据不同的控制器直接将实现与接口连接起来,对吧? 视情况而定。如果您只有一个实现,并且您不打算在将来添加另一个实现,则可以不使用接口。以上是关于LARAVEL:如何使用 SOLID 原则的开闭原则?的主要内容,如果未能解决你的问题,请参考以下文章