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

ほんとのおわり