ホームページ  >  記事  >  バックエンド開発  >  laravelの依存性注入と制御の反転

laravelの依存性注入と制御の反転

WBOY
WBOYオリジナル
2016-06-23 13:06:201396ブラウズ

依存性注入と制御の反転

依存性注入 この用語に初めて触れたとき、私は今でも少し混乱しています。そこで、今日は Laravel での依存性注入について説明します。それをよく理解してください。 コントロールの反転 第一印象とはとても奥深い言葉です。 。 。リバースコントロールっぽい?分かりませんか?それからまっすぐにしてください!

出発点

依存とは何ですか

私はあなたなしでは生きていけません、ならば、あなたは私の依存物です。 率直に言うと、

は私のものではありませんが、私に必要なものであり、私が依存しているものです。外部から提供する必要があるものはすべて依存関係の注入が必要です。

コードで説明しましょう:

class Boy {  protected $girl;  public function __construct(Girl $girl) {    $this->girl = $girl;  }}class Girl {  ...}$boy = new Boy();  // Error; Boy must have girlfriend!// so 必须要给他一个女朋友才行 $girl = new Girl();$boy = new Boy($girl); // Right! So Happy!

上記のコードから、Boy は Girl に強く依存しており、構築中に Girl のインスタンスを注入する必要があることがわかります。

では、なぜ依存性注入という概念があるのでしょうか? 依存性注入はどのような問題を解決しますか?

上記のコードを、学習時に書いたコードに変更してみましょう:

class Boy {  protected $girl;  public function __construct() {    $this->girl = new Girl();  }}

この方法と前の方法の違いは何ですか?

ボーイのガールフレンドがボーイの体にハードコードされていることがわかります。 。 。 ボーイは生まれ変わって、違うタイプのガールフレンドが欲しくなるたびに、裸にならなければなりません。 。 。 (⊙o⊙)…

ある日、ボーイはロリガールが大好きで、彼女を彼女にしてほしかったのです。 。 。何をするか? 自分自身を生まれ変わらせます。 。 。自分自身を明らかにしましょう。 。 。女の子を捨てなさい。 。 。ロリガールを中に押し込んでください。 。 。

rreee

ある日、ボーイはユウお姉さんに恋をしてしまいました…(⊙o⊙)… ボーイはとてもイライラしていました。 。 。

気分が良くないですか?私に誠実に接してくれる人に出会うたびに、私はこうやって自分を苦しめなければなりません。 。 。

少年は言いました、私は強くなりたいです。何度も変えられたくない!

分かった、ボーイを強くしましょう:

rreee

ボーイは、ついに自分自身を開かずに別の人生を経験できることにとても満足しています。 。 。とても幸せです!

概要

ほとんどのアプリケーションは、ビジネス ロジックを実装するために相互に連携する 2 つ以上のクラスで構成されているため、各オブジェクトは連携するオブジェクト (つまり、オブジェクトが依存するオブジェクト) を取得する必要があります。 ) 参照。この取得プロセスが単独で実装される場合、コードは高度に結合され、保守とデバッグが困難になります。

だからこそ、依存性注入の概念が存在します。依存性注入は次の問題を解決します:

    依存関係間の分離
  • Mock に便利な単体テスト
=。 = 以前の依存関係の注入では、実際には依存関係を手動で注入する必要があります。プログラマーとして、この非効率な注入方法をどのように許容できるでしょうか? まず、

IOC の概念を理解しましょう。 制御の反転 (Inversion Of Control、IOC)

制御の反転

は、コンピューター コード間の結合を減らすために使用できるオブジェクト指向プログラミングの設計原則です。最も一般的な方法は Dependency Injection (DI) と呼ばれ、もう 1 つは「Dependency Lookup」と呼ばれます。制御の反転により、オブジェクトが作成されると、システム内のすべてのオブジェクトを制御する外部エンティティが、依存するオブジェクトの参照をそれに渡します。依存関係がオブジェクトに注入されるとも言えます。 言い換えると、制御システムが必要です。この制御システムでは、いくつかのオブジェクトのエンティティ、またはオブジェクトの説明を保存し、オブジェクトの作成時にそのオブジェクトが依存するオブジェクトの参照を渡します。 Laravelのサービスコンテナは、laravelの核となるこの効率的な制御システムです。 laravel が自動依存関係注入をどのように実装するかを見てみましょう。

laravel での依存性注入

ここで、ドキュメントに示されている例を見ると、簡単に理解できるはずです:

class LoliGirl {}class Boy {  protected $girl;   public function __construct() {      //  $this->girl = new Girl();  // sorry...      $this->girl = new LoliGirl();  }}

この例では、PurchasePodcast ジョブは、ポッドキャストが購入されたときに電子メールを送信する必要があります。電子メールを送信できるサービスを注入します

サービスは注入されるため、簡単に「モック」したり、ダミーの実装を作成したりすることもできます。アプリケーションをテストするときのメーラーです。

laravelの依存関係注入と言えば、laravelのサービスコンテナを理解する必要があります

サービスコンテナ(サービスコンテナ)

Laravelサービスコンテナは、クラスの依存関係を管理し、依存関係注入を実行するための強力なツールです。依存関係の注入とは、本質的に次のことを意味する派手なフレーズです。クラスの依存関係は、コンストラクター、場合によっては「セッター」メソッドを介してクラスに「注入」されます。

サービス コンテナーが制御反転のコンテナ 上記のスケジューリングシステムです。依存関係の注入は、コンストラクターまたはセッター メソッドで実装できます。

如果我们仔细研究了Service Container我们就会发现laravel的服务容器中只存储了对象的描述,而并不需要知道如何具体的去构造一个对象,因为它会根据php的反射服务去自动解析具体化一个对象。

反射

在计算机科学中,反射是指计算机在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力。用来比喻说,那种程序能够“观察”并且修改自己的行为。

支持反射的语言提供了一些在低级语言中难以实现的运行时特性。这些特性包括

  • 作为一个第一类对象发现并修改源代码的结构(如代码块、类、方法、协议等)。
  • 将跟class或function匹配的转换成class或function的调用或引用。
  • 在运行时像对待源代码语句一样计算字符串。
  • 创建一个新的语言字节码解释器来给编程结构一个新的意义或用途。

PHP实现的反射可以在官网文档中进行查看: 反射API

Example
$reflector = new ReflectionClass('App\User');if ($reflector->isInstantiable()) {  $user = $refector->newInstance(); //in other case you can send any arguments}

laravel的服务容器的build方法中需要通过反射服务来解析依赖关系,比如说construct函数中需要传递的依赖参数有哪些? 它就需要用到如下方法:

   $constructor = $reflector->getConstructor();   // If there are no constructors, that means there are no dependencies then   // we can just resolve the instances of the objects right away, without   // resolving any other types or dependencies out of these containers.   if (is_null($constructor)) {       array_pop($this->buildStack);       return new $concrete;   }   $dependencies = $constructor->getParameters();

现在我们应该对laravel如何实现依赖的自动注入有点想法了吧?来整理一下疑问:

  • 如何实现依赖的自动注入? (控制反转,利用反射)
  • 依赖注入需要哪些东东? (整理依赖关系[ construct | setter ],还要解析依赖传递引用)
  • 怎么解析依赖?

你可能会问为什么要问怎么解析依赖?解析依赖肯定是要用到反射的啦,反射,你知道类名不就可以直接解析了吗?

其实。。。不是这样的。。。(@ο@)

很多时候我们为了提高代码的扩展性和维护性,在编写类时依赖的是接口或抽象类,而并不是一个具体的实现类。明白了吗?依赖解析的时候如果只解析到接口或抽象类,然后利用反射,那么这个依赖肯定是错误的。

那么我们就需要在调度系统中注入相关依赖的映射关系,然后在需要的时候正确的解析关系。 比如说, 喂, 我需要一个 A, 你别给我 B 啊。

$container->bind('a', function () {  return new B();  // just this for you});$a = $container->make('a');

总结

  • 依赖注入是控制反转的一种实现,实现代码解耦,便于单元测试。因为它并不需要了解自身所依赖的类,而只需要知道所依赖的类实现了自身所需要的方法就可以了。你需要我,你却不认识我/(ㄒoㄒ)/~~
  • 控制反转提供一种调控系统,实现依赖解析的自动注入,一般配合容器提供依赖对象实例的引用。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。