真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

laravel服務(wù)容器的IoC模式是什么

這篇文章主要介紹“l(fā)aravel服務(wù)容器的IoC模式是什么”,在日常操作中,相信很多人在laravel服務(wù)容器的IoC模式是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”laravel服務(wù)容器的IoC模式是什么”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

網(wǎng)頁設(shè)計是網(wǎng)站建設(shè)的前奏,好的網(wǎng)頁設(shè)計更深度的剖析產(chǎn)品和設(shè)計風(fēng)格定位,結(jié)合最新的網(wǎng)頁設(shè)計流行趨勢,與WVI應(yīng)用標(biāo)準(zhǔn),設(shè)計出具企業(yè)表現(xiàn)力,大器而深穩(wěn)的網(wǎng)站界面設(shè)。成都創(chuàng)新互聯(lián)公司于2013年開始,是成都網(wǎng)站建設(shè)公司:提供企業(yè)網(wǎng)站設(shè)計,高端網(wǎng)站設(shè)計,營銷型企業(yè)網(wǎng)站建設(shè)方案,成都響應(yīng)式網(wǎng)站建設(shè)公司,小程序設(shè)計,專業(yè)建站公司做網(wǎng)站。

1、依賴

IoC模式主要是用來解決系統(tǒng)組件之間相互依賴關(guān)系的一種模式。那么什么是依賴呢?下面給出依賴的實例

trafficTool = new Foot();
    }

    public function go_to_school()
    {
        $this->trafficTool->go();
    }
}

$student = new Student();
$student->go_to_school();

這里要實現(xiàn)的功能是學(xué)生去學(xué)校,當(dāng)創(chuàng)建了一個學(xué)生實例的時候,同時也創(chuàng)建了一個交通工具的實例??梢钥吹綄W(xué)生和交通工具之間不可避免的產(chǎn)生了一個依賴。在程序中依賴可以理解為一個對象實現(xiàn)某個功能時需要其他對象相關(guān)功能的支持。

當(dāng)然交通工具還有很多,接著完善代碼

trafficTool = new Foot();
        //$this->trafficTool = new Car();
        //$this->trafficTool = new Bicycle();
        /*
         *
         *
         *
         *
         * more and more
         *
         *
         *
         *
         */
    }

    public function go_to_school()
    {
        $this->trafficTool->go();
    }
}

$student = new Student();
$student->go_to_school();

是不是很恐怖!當(dāng)用new關(guān)鍵字在一個組件內(nèi)部實例化一個對象時就解決了一個依賴,但同時也引入了另一個嚴(yán)重的問題——耦合。在簡單情況下可能看不出耦合有多大問題,但是如果需求改變,如需要實例化的交通工具是自行車、汽車甚至是在設(shè)計中還不太清楚的工具時,就需要改變實例化的對象,如果又有很多地方用到了這段代碼,而這個程序又不是你寫的,這時你面對的將是噩夢。所以,這里我們不應(yīng)該在學(xué)生內(nèi)部固化’交通工具‘的初始化行為,而轉(zhuǎn)由外部負責(zé)

2、簡單工廠模式

原理:由一個工廠類根據(jù)傳入的參數(shù)(一般是字符串參數(shù)),動態(tài)決定應(yīng)該創(chuàng)建哪一個產(chǎn)品子類(這 些產(chǎn)品子類繼承自同一個父類或接口)的實例,并以父類形式返回。

適用情況:所有的產(chǎn)品子類都有同一個父類(或接口),屬于同一個產(chǎn)品系列 產(chǎn)品子類比較少的、創(chuàng)建操作比較簡單 。

在前面的實例中我們知道,交通工具的實例化過程是經(jīng)常需要改變的,所以我們將這部分提取到外部來管理,這也就體現(xiàn)了面向?qū)ο笤O(shè)計的一個原則,及找出程序中會變化的方面然后將其和固定不變的方面相分離。一種簡單的實現(xiàn)方案是利用工廠模式,這里我們用簡單工廠模式實現(xiàn)。實例如下:

class TrafficToolFactory
{
    public function createTrafficTool($name)
    {
        switch ($name){
            case 'Foot':
                return new Foot();
                break;
            case 'Car':
                return new Car();
                break;
            case 'Bicycle':
                return new Bicycle();
                break;
            default:
                exit('set trafficTool error!');
                break;
        }
    }
}

class Student
{
    private $trafficTool;
    public function __construct($trafficTool)
    {
        //通過工廠產(chǎn)生依賴的交通工具實例
        $factory = new TrafficToolFactory();
        $this->trafficTool = $factory->createTrafficTool($trafficTool);
    }
    public function go_to_school(){
        $this->trafficTool->go();
    }
}

$student = new Student('Car');
//$student2 = new Student('Foot');
//$student3 = new Student('Bicycle');
$student->go_to_school();

這里我們添加了“交通工具”工廠,在學(xué)生實例化的過程中指定需要的交通工具,則工廠生產(chǎn)相應(yīng)的交通工具實例。在一些簡單的情況下,簡單工廠模式可以解決這個問題。我們看到學(xué)生和交通工具之間的依賴關(guān)系沒有了,但是卻變成學(xué)生和交通工具工廠之間的依賴。當(dāng)需求增加時,我們需要修改簡單工廠,如果依賴增多,工廠將十分龐大,依然不利于維護。下一步就是我們今天的主要配角 —— DI

3、DI(Dependency Injection 依賴注入)

本文中提到的一系列依賴,只要不是由內(nèi)部產(chǎn)生(比如初始化、構(gòu)造函數(shù) __construct 中通過工廠方法、自行手動 new 的),而是由外部以參數(shù)或其他形式注入的,都屬于依賴注入(DependencyInjection簡稱DI) 。實例如下:

class Student
{
    private $trafficTool;
    public function __construct(Go_To_School $trafficTool)
    {
        $this->trafficTool = $trafficTool;
    }
    public function go_to_school(){
        $this->trafficTool->go();
    }
}

$car = new Car();
$student = new Student($car);
$student->go_to_school();

現(xiàn)在初始化學(xué)生類時提供的參數(shù)必須是Go_To_School接口類的一個實例,即通過依賴注入的方式解決依賴問題,否則就會提示出錯。這里要注意,依賴注入要以接口的形式進行限制,不能隨意開放

4、IoC容器(Inversion of Control 控制反轉(zhuǎn))

IoC是將設(shè)計好的類交給系統(tǒng)去控制,而不是在類內(nèi)部控制。這稱為控制反轉(zhuǎn)。上例中我們是通過手動注入依賴,而IoC容器實現(xiàn)了依賴的自動注入。下面給出一個簡化版的例子。里面涉及到反射機制,網(wǎng)上有很多關(guān)于反射機制的講解,讀者可以自行查找,這里就不細說了。

class Container {

    //用于裝提供實例的回調(diào)函數(shù),真正的容器還會裝實例等其他內(nèi)容
    //從而實現(xiàn)單例等高級功能
    protected $bindings = [];

    //綁定接口和生成相應(yīng)實例的回調(diào)函數(shù)
    public function bind($abstract, $concrete=null, $shared=false) {

        //如果提供的參數(shù)不是回調(diào)函數(shù),則產(chǎn)生默認的回調(diào)函數(shù)
        if(!$concrete instanceof Closure) {
            $concrete = $this->getClosure($abstract, $concrete);
        }

        $this->bindings[$abstract] = compact('concrete', 'shared');
    }

    //默認生成實例的回調(diào)函數(shù)
    protected function getClosure($abstract, $concrete) {

        return function($container) use ($abstract, $concrete) {
            $method = ($abstract == $concrete) ? 'build' : 'make';
            return $container->$method($concrete);
        };

    }
    //解決接口和要實例化類之間的依賴關(guān)系
    public function make($abstract) {

        $concrete = $this->getConcrete($abstract);

        if($this->isBuildable($concrete, $abstract)) {
            $object = $this->build($concrete);
        } else {
            $object = $this->make($concrete);
        }

        return $object;
    }

    protected function isBuildable($concrete, $abstract) {
        return $concrete === $abstract || $concrete instanceof Closure;
    }

    //獲取綁定的回調(diào)函數(shù)
    protected function getConcrete($abstract) {
        if(!isset($this->bindings[$abstract])) {
            return $abstract;
        }

        return $this->bindings[$abstract]['concrete'];
    }

    //實例化對象
    public function build($concrete) {

        if($concrete instanceof Closure) {
            return $concrete($this);
        }

        $reflector = new ReflectionClass($concrete);

        if(!$reflector->isInstantiable()) {
            echo $message = "Target [$concrete] is not instantiable";
        }

        $constructor = $reflector->getConstructor();
        if(is_null($constructor)) {
            return new $concrete;
        }

        $dependencies = $constructor->getParameters();
        $instances = $this->getDependencies($dependencies);

        return $reflector->newInstanceArgs($instances);
    }

    //解決通過反射機制實例化對象時的依賴
    protected function getDependencies($parameters) {
        $dependencies = [];
        foreach($parameters as $parameter) {
            $dependency = $parameter->getClass();
            if(is_null($dependency)) {
                $dependencies[] = NULL;
            } else {
                $dependencies[] = $this->resolveClass($parameter);
            }
        }

        return (array)$dependencies;
    }

    protected function resolveClass(ReflectionParameter $parameter) {
        return $this->make($parameter->getClass()->name);
    }

}

這就是簡化版的IoC容器類,使用bind()函數(shù)進行服務(wù)綁定,使用make()函數(shù)來進行解析,最后在容器內(nèi)由build()函數(shù)創(chuàng)建并返回實例。下面是具體如何使用

//實例化IOC容器
$ioc = new Container();

//填充容器
$ioc->bind('Go_To_School', 'Car');	//第一個參數(shù)'Go_To_School'是接口,第二個參數(shù)'Car'是交通工具類
$ioc->bind('student', 'Student');    //第一個參數(shù)'student'可以理解為服務(wù)別名,用make()實例化的時候直接使用別名即可,第二個參數(shù)'Student'是學(xué)生類

//通過容器實現(xiàn)依賴注入,完成類的實例化
$student = $ioc->make('student');
$student->go_to_school();

填充容器的時候也可以直接綁定自定義的回調(diào)函數(shù):

$ioc->bind('Go_To_School', function (){
    return new Car();
});

現(xiàn)在,我們不僅解除了學(xué)生類與交通工具類的依賴關(guān)系,而且容器類沒有和他們產(chǎn)生任何依賴。我們通過注冊、綁定(bind)的方式向容器中添加一段可以被執(zhí)行的回調(diào)(可以是匿名函數(shù)、非匿名函數(shù)、類的方法)作為創(chuàng)建一個類的實例的方法,只有在真正的創(chuàng)建(make)操作被調(diào)用執(zhí)行時,才會觸發(fā)。這樣一種方式,使得我們更容易在創(chuàng)建一個實例的同時解決其依賴關(guān)系,并且更加靈活。當(dāng)有新的需求,只需另外綁定一個回調(diào)即可。例如現(xiàn)在我們想步行去學(xué)校,只要再綁定$ioc->bind('Go_To_School', 'Foot');就可以了。用何種方式去學(xué)校,我們可以自由的選擇。

通過上述例子可以看到IOC容器最核心的功能,解決依賴注入的根本問題。在實現(xiàn)過程中,沒有用new關(guān)鍵字來實例化對象,不需要人來關(guān)注組件之間的依賴關(guān)系,只要在容器填充過程中理順接口和實現(xiàn)類之間的關(guān)系及實現(xiàn)類與依賴接口之間的關(guān)系就可以流水線式的完成實現(xiàn)類的實例化過程。

到此,關(guān)于“l(fā)aravel服務(wù)容器的IoC模式是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
文章題目:laravel服務(wù)容器的IoC模式是什么
網(wǎng)頁路徑:http://weahome.cn/article/pcgoph.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部