控制反转

介绍

Inversion of Control,缩写为IoC。
是一种设计原则,可以减小模块之间的耦合,使代码可维护性变高。
IoC提倡:

  1. 高层模块不应该依赖底层模块。两个都应该依赖抽象
  2. 抽象不应该依赖细节,细节应该依赖抽象
  3. 针对接口编程,不要针对实现编程

下面看一个用依赖注入设计模式,实现控制反转的例子:
依赖注入就是在本类中使用其他类的话,不是在本类中实例化,而是通过方法把外部的类注入进来使用,可提高代码重用和可读性。

依赖注入的例子

拿我之前写的compose pack举例:
https://github.com/OX007/easywechatshare

src/Share.php中的Share类需要使用EasyWeChat\Foundation\Application这个实例。
如果在该类中实例化EasyWeChat类则需要配置很多参数,极不易使用。

用依赖注入实现就可以如下代码所示。
这样的话,别人用的时候,就可以把自己的EasyWeChat\Foundation\Application实例传进来就可以,非常方便。

class Share
{
    private $wechatApp;
    /**
     * init wechat option
     * 
     * @param     EasyWeChat\Foundation\Application
     */
    public function __construct(Application $wechatApp)
    {
        $this->wechatApp = $wechatApp;
    }
    
    ...
 }

从Laravel底层看控制反转的例子

例如从vendor/laravel/framework/src/Illuminate/Mail/SendQueuedMailable.php
中可以看出,handle方法的 $mailer参数可以是实现了Illuminate\Contracts\Mail\Mailer接口的任何一个实例,这时handle就无须关注要执行的实例具体内容,直接执行即可,反正实例是根据接口类实现的,send方法都会有。
这也正遵循了控制反转的原则,这样的话,多个类的之间的依赖复杂性就降低了,是面向接口编程,都依赖抽象,让实现变得松散耦合

<?php

namespace Illuminate\Mail;

use Illuminate\Contracts\Mail\Mailer as MailerContract;
use Illuminate\Contracts\Mail\Mailable as MailableContract;

class SendQueuedMailable
{
    /**
     * The mailable message instance.
     *
     * @var Mailable
     */
    protected $mailable;

    /**
     * Create a new job instance.
     *
     * @param  \Illuminate\Contracts\Mail\Mailable  $mailable
     * @return void
     */
    public function __construct(MailableContract $mailable)
    {
        $this->mailable = $mailable;
    }
	
    /**
     * Handle the queued job.
     *
     * @param  \Illuminate\Contracts\Mail\Mailer  $mailer
     * @return void
     */
    public function handle(MailerContract $mailer)
    {
        $mailer->send($this->mailable);
    }
}

再写一个更容易理解的例子

<?php

interface Storage{
	public function open();
}

class DatabaseStorage implements Storage {
	public function open() {
		echo 'open db Storage';
	}
}

class FileStorage implements Storage {
	public function open() {
		echo 'open file Storage';
	}
}

class MyController {
	
	private $Storage;

	public function initEngine(Storage $Storage)
	{
		$this->Storage = $Storage;
	}

	public function open()
	{
		$this->Storage->open();
	}
}

$MyController = new MyController;
$MyController->initEngine(new FileStorage);
$MyController->open(); // open file Storage

?>

参考资料:
https://github.com/seekerliu/laravel-tips/blob/master/what-is-dependency-injection.md
https://medium.com/@amitkma/understanding-inversion-of-control-ioc-principle-163b1dc97454
https://en.wikipedia.org/wiki/Dependency_injection
https://cloud.tencent.com/developer/article/1191956

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值