编程语言
首页 > 编程语言> > php – LARAVEL:如何使用Open Close原理的SOLID原理?

php – LARAVEL:如何使用Open Close原理的SOLID原理?

作者:互联网

我有一个以下结构来使用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);

我知道我可以通过服务提供商将接口与类绑定,但如果我想实现不同的支付实现,那么我将无法更改类,对吧?

如果我以错误的方式这样做,请告诉我.

解决方法:

这就是服务容器所代表的含义.你应该使用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原则.

标签:php,solid-principles,laravel,open-closed-principle
来源: https://codeday.me/bug/20190522/1152356.html