LaravelでDIを扱う仕組み ~Service ContainerとService Provider~
by
2bo
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Slide 1
Slide 1 text
LaravelでDIを扱う仕組み ~Service ContainerとService Provider~ 19.12.05 @AkogareSe
Slide 2
Slide 2 text
● @AkogareSe ● エンジニア8年目 ○ SIer->社内エンジニア ○ PHP歴1年 ○ Laravel勉強中 ○ AWS/Vue.js勉強したい ● 旅行好き ● IKEAシャークかわいい 自己紹介
Slide 3
Slide 3 text
話すこと ● Dependency Injection(DI)の簡単な説明 ● LaravelでDIを扱うための機能 ○ Service Container ○ Service Provider
Slide 4
Slide 4 text
DIとは? ● 日本語では「依存性の注入」という ● オブジェクト指向プログラミングのデザインパターン
Slide 5
Slide 5 text
依存とは? ● あるクラスの処理が別の具体クラスの存在を前提にしていること ○ 別クラスのオブジェクトを処理の中で生成すること
Slide 6
Slide 6 text
依存の例
Slide 7
Slide 7 text
Mailer ------------------------------------------------------- send() RecommendService ------------------------------------------------------- recommend() RecommendServiceクラスが Mailerに依存している状態 依存 利用
Slide 8
Slide 8 text
依存の何が問題? ● 単体テストしづらい ○ テストの時はメール送りたくない ○ Mailerにテスト用の分岐処理を追加する ● 依存する側の再利用性の低下 ○ メールではなく、場合によってSMSで送りたい ○ RecommendServiceをそのまま利用できない
Slide 9
Slide 9 text
DI = 利用するオブジェクトを外部から注入 ● 利用するオブジェクトを引数で渡す ● パターン ○ コンストラクタ ○ メソッド ○ セッター
Slide 10
Slide 10 text
DIの例
Slide 11
Slide 11 text
Mailer RecommendService Mailerに依存していない send()を持つクラスであればよい 利用
Slide 12
Slide 12 text
DIの効果 ● 振る舞いを外部から変えられる ○ send()さえ実装されていればどんなオブジェクトでもよい ■ 実際にはメールを送らないもの ■ SMS送信するもの ■ Line送信するもの ■ etc
Slide 13
Slide 13 text
DIの課題とコンテナ ● 課題 ○ 注入するオブジェクトの生成をどこでやるか? ○ オブジェクトが多かったり、入れ子だと生成が大変 ■ A,B,C ■ A->B->C ● DIコンテナ ○ DIに必要な機能を提供するソフト/フレームワーク ○ 注入するオブジェクトの生成、管理を担う
Slide 14
Slide 14 text
ここまではわかった
Slide 15
Slide 15 text
ここからはLaravelの話
Slide 16
Slide 16 text
Laravel勉強中出会った謎の用語 ● “Service Container” と “Service Provider” ● どうやらDIに関連するものらしい...?
Slide 17
Slide 17 text
ドキュメント読んでみた...けど??? ● Service Container ❝Laravelのサービスコンテナは、クラス間の依存を管理する強力な管理ツールです。❞ ● Service Provider ❝サービスプロバイダは、 Laravelアプリケーション全体の起動処理における、初めの心臓部です。 ❞ https://readouble.com/laravel/6.x/ja/ より
Slide 18
Slide 18 text
No content
Slide 19
Slide 19 text
つまり何? ● Service Container ○ DIコンテナ ● Service Provider ○ Laravelのサービス(機能)の初期化処理を書くクラス ○ SCへオブジェクトの生成方法を登録する場所として使われる
Slide 20
Slide 20 text
SCの自動注入機能
Slide 21
Slide 21 text
Hello ------------------------------------------------------- say() GreetingController ------------------------------------------------------- geet() コントローラメソッドの型宣言を見て オブジェクトを自動で生成/注入 依存 利用
Slide 22
Slide 22 text
これだと依存したまま
Slide 23
Slide 23 text
抽象化する
Slide 24
Slide 24 text
GreetingInterface ------------------------------------- say() GreetingController ------------------------------------ greet() 依存 Hello -------------------------------------- say() 実装 GreetingInterfaceに依存するように変更
Slide 25
Slide 25 text
これだけでは動かない
Slide 26
Slide 26 text
SCにインターフェイスとオブジェクトの対応を登録 ● bind()で登録 ● GreetingInterfaceの型指定に対して、Helloオブジェクトを生成・注入させる
Slide 27
Slide 27 text
結局Helloに依存?
Slide 28
Slide 28 text
bind()用の場所がある
Slide 29
Slide 29 text
Service Provider
Slide 30
Slide 30 text
Service Provider ● register()はSCへのバインド処理を書くための既定メソッド ● Laravelの初期化処理時に実行される
Slide 31
Slide 31 text
まとめ ● DI ○ 利用するオブジェクトを引数で渡してやること ○ 振る舞いを後から変えられる ● DIコンテナ ○ DIに必要な機能を提供してくれるもの ● Service Container ○ LaravelのDIコンテナ ● Service Provider ○ SCにオブジェクトの生成ルールを登録するところ
Slide 32
Slide 32 text
おわり
Slide 33
Slide 33 text
おまけ
Slide 34
Slide 34 text
GreetingInterface ------------------------------------- say() GreetingController ------------------------------------ greet() 依存 Hello ------------ say() 実装 GreetingInterfaceを実装したGoodByeクラスを追加 GoodBye ------------ say() 実装
Slide 35
Slide 35 text
bind()メソッドにはクロージャを渡すこともできる ● クロージャの戻値はSCに生成してほしいインスタンス ● 動的なバインドが可能
Slide 36
Slide 36 text
ほんとのおわり