Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
CakePHPで学ぶDIコンテナ / Learn a DI Container through...
Search
itosho
December 12, 2020
Programming
2k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
CakePHPで学ぶDIコンテナ / Learn a DI Container through CakePHP
PHPカンファレンス2020の登壇資料です。
itosho
December 12, 2020
More Decks by itosho
See All by itosho
【2025年版】インターネットサービスの育て方 / How to Grow and Scale Internet Services 2025
itosho
0
220
Windsurf Rulesでどう自分のクローンをつくるか / How can I make a clone of myself in Windsurf Rules
itosho
0
130
Text EditorとしてのWindsurf / Windsurf as a Text Editor
itosho
0
330
【2024年版】インターネットサービスの育て方 / How to Grow and Scale Internet Services
itosho
0
120
打線組という個人サービスを Goで開発している話 / Indie Service Development by Go
itosho
1
200
Components Reconsidered
itosho
1
2.4k
打線組を支える技術 / The Technology Behind Dasengumi
itosho
0
69
組織をスケールさせるためのTech Vision / Connehito Tech Vision for Growing Our Team
itosho
2
700
生きのびるためのインディー開発 / Indie Development to Survive
itosho
0
62
Other Decks in Programming
See All in Programming
その問い、本当に正しいですか?AI時代のエンジニアに必要な哲学と認知科学 / ai-philosophy-cognitive-science
minodriven
14
6.4k
Spec Driven Development | AI Summit Lisbon
danielsogl
PRO
0
210
AI駆動開発を妨げる技術的負債の解消アプローチ / ai-refactoring-approach
minodriven
15
7.3k
スマートグラスで並列バイブコーディング
hyshu
0
260
SREは、MCPとSRE Agentをこう使え!
kazumax55
0
120
不変条件と整合性境界—ビジネスが決める設計判断と実現パターン / Invariants and Consistency Boundaries
nrslib
14
5.9k
Strategic Design in the Frontend: Moduliths & Micro Frontends @DDDEurope
manfredsteyer
PRO
0
130
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
200
そのテスト、説明できますか?~LWテスト戦略FW~のご紹介
nakahara
0
170
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
600
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5.4k
ふつうのFeature Flag実践入門
irof
8
4.2k
Featured
See All Featured
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
280
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.1k
What's in a price? How to price your products and services
michaelherold
247
13k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2.1k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.4k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
580
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
200
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.3k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.5k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
KATA
mclloyd
PRO
35
15k
Transcript
CakePHPで学ぶDIコンテナ PHPカンファレンス2020 @itosho
こんにちは!
Discordみてるので、盛り上げてください!
どんな25分になるか? This session’s goal
今日話すこと ・DIとDIコンテナについての概要 ・CakePHPに新しく導入されるDIコンテナの使い方 ・DIコンテナがCakePHPに導入される意味
今日話さないこと ・DI関連の突っ込んだ話 ・例えば、Autowiringやサービスロケーターパターンとの比較は話しません ・CakePHPのDIコンテナの実装の詳細 ・今回は裏側ではなく、使い方にフォーカスします ※ちょっと聴きたい発表と違うな…と思った方はTrack2の「今こそ理解する、PHPの日時計算」がおすすめです! (弊社の同僚が登壇しているので宣伝)
皆さんをこんな気持ちにしたい! ・(DIに馴染みがない人)DIやDIコンテナを使ってみよう! ・(CakePHP使っている人)CakePHPでもDIコンテナを使ってみよう! ・普段使っているフレームワークの今後について考えてみよう!
自己紹介 ・伊藤 翔 @itoho ・コネヒト株式会社 執行役員兼CTO ・Backend Engineer / CakePHP
Contributor ・エンジニアキャリア(12年): 金融系SIer->Web系受託->CGMサービス->コネヒト(コミュニティサービス) ・FW遍歴: 独自のFW->Ruby on Rails->CakePHP->echo ・バイアスがあると思うので、切り口の一つとして聞いてください ・議論のきっかけになればいいなと思っています!
DIとDIコンテナを知る What’s a DI and a DI Container?
そもそも、DIとは? ・DI = 「Dependency Injection」の略 ・日本語で言うと「依存性の注入」 “依存性の注入とは、コンポーネント間の依存関係をプログラムのソースコードから排除するために、外部の設定ファ イルなどでオブジェクトを注入できるようにするソフトウェアパターンである。”(Wikipediaから引用)
そもそも、DIとは? ・DI = 「Dependency Injection」の略 ・日本語で言うと「依存性の注入」 “依存性の注入とは、コンポーネント間の依存関係をプログラムのソースコードから排除するために、外部の設定ファ イルなどでオブジェクトを注入できるようにするソフトウェアパターンである。”(Wikipediaから引用) なるほど、分からん
DIの歴史を知る ・DIという言葉自体はマーティン・ファウラー氏が作成(2004年頃) ・似た概念として「Inversion of Control」(制御の反転)が存在 ・Ioc自体は1994年頃、ロバート・C. マーチン氏(ボブおじさん)が提唱 “制御の反転とは、なんらかの種類のプログラムにおいて、プロシージャを「呼び出す側」と「呼び出される側」が、 従来のプログラムとは逆になるようにする、ということである。”(Wikipediaから引用)
DIの歴史を知る ・DIという言葉自体はマーティン・ファウラー氏が作成(2004年頃) ・似た概念として「Inversion of Control」(制御の反転)が存在 ・Ioc自体は1994年頃、ロバート・C. マーチン氏(ボブおじさん)が提唱 “制御の反転とは、なんらかの種類のプログラムにおいて、プロシージャを「呼び出す側」と「呼び出される側」が、 従来のプログラムとは逆になるようにする、ということである。”(Wikipediaから引用) コードで話そう
用語の整理 ・サービス: 特定の機能を提供するオブジェクト / 使われる(依存される)側 ・例: AWS SESを使ったメール送信機能を持つクラス、SendGridを使ったメール送信機能を持つクラスなど ・クライアント: サービスを利用するオブジェクト
/ 使う(依存する)側 ・例: 上述のメール送信機能を利用するコントローラークラスなど ※以降のスライドで登場するサンプルコードの置き場所: https://github.com/itosho/x-cakephp-di-container (スライド内では重要な部分のみを抜粋しています)
▪サービスのコード
▪DIじゃないコード
問題点 ・一言で言うと、クライアントとサービスが密結合になっている ・クライアントのテスト時にSESが必要になる(実際に送信されてしまう) ・SESからSendGridへ変更する場合、クライアントの修正が必須
問題点 ・一言で言うと、クライアントとサービスが密結合になっている ・クライアントのテスト時にSESが必要になる(実際に送信されてしまう) ・SESからSendGridへ変更する場合、クライアントの修正が必須 そこで登場するのがDI
▪DIなコード(具体に依存)
DIの特徴 ・オブジェクトの生成と利用の分離 ・これにより、クライアントの修正なしにSESの送信先を変更することが出来る ・制御の反転 ・❌クライアントがサービスを呼ぶ ・⭕サービスが外部からクライアントに注入 ・今回の注入方法は「コンストラクターインジェクション」 ・クライアントが具体のサービスに依存していることには変わりがない
▪サービスのコード(インタフェースあり)
▪DIなコード(抽象に依存)
実装ではなく抽象に依存させる ・一言で言うと、クライアントとサービスが疎結合になっている ・モックを利用することができ、クライアントのテストが容易になる ・SESからSendGridへ変更してもクライアントの修正は不要 ・実際にクライアントの修正が全く必要ないケースは稀だが、影響範囲は相対的に軽微になるはず
DIの課題 ・注入するオブジェクトが増えると…? ・オブジェクトの依存関係が複雑になると…? ・オブジェクトを生成するコードの管理が大変なことに!
DIの課題 ・注入するオブジェクトが増えると…? ・オブジェクトの依存関係が複雑になると…? ・オブジェクトを生成するコードの管理が大変なことに! そこで登場するのがDIコンテナ
DIコンテナ ・アプリケーションにDI機能を提供する仕組み ・オブジェクトの生成を一手に引き受ける ・PHPでの活用 / 実装例: PSR-11, Pimple, league/container, PHP-DIなど
▪DIコンテナ(league/container)を用いたコード
ここまでのまとめ ・DIはソフトウェアを密結合から疎結合にする手法 ・外部からオブジェクトを注入することでモジュール間の依存関係を薄くする ・具体の実装ではなく、抽象に依存させるのがポイント ・DIコンテナはDI対象となるオブジェクトの管理を一箇所にまとめた箱
CakePHPのDIコンテナを試す Try a DI Container on CakePHP
CakePHPとDIコンテナ ・CakePHPはこれまでDIコンテナとは距離を取っていた(と思う) ・下記はDIコンテナについてのIssueの冒頭: https://github.com/cakephp/cakephp/issues/14865
CakePHPにおける依存関係管理の歴史 ・Controllerなどに外部からオブジェクトを注入する場合、サービスロケー ター的な手法を採用してきた ・サービスロケーターと言い切っていいかは自信がない…(つぶやき) ・CakePHP2系: ClassRegistryというグローバルなレジストリを使用 ・CakePHP3系: 局所的なレジストリを作る方針に変更 ・Componentに対してはComponentRegistry、Behaviorに対してはBehaviorRegistryなど
▪これまでのCakePHPの依存管理
CakePHPにDIコンテナがやって来た! ・4.2系からDIコンテナが導入される! ・2020/12/11時点でRC1版がリリース ・ちなみにコンストラクターインジェクションではなく、メソッドインジェクションが採用された ・ライブラリとしては「league/container」を利用 ・PSR-11に準拠していれば、ライブラリは差し替えることが出来そう ・「EntryPoint」(Controller, Command)のみDIすることが出来る ・View, Helper,
Table, Mailer, Behaviorは出来ない(アプリケーション層から遠くDIする難易度が高いため) ・DIコンテナの持つ自由度とCakePHPの持つ制約を両立させた?
CakePHPにDIコンテナがやって来た! ・4.2系からDIコンテナが導入される! ・2020/12/11時点でRC1版がリリース ・ちなみにコンストラクターインジェクションではなく、メソッドインジェクションが採用された ・ライブラリとしては「league/container」を利用 ・PSR-11に準拠していれば、ライブラリは差し替えることが出来そう ・「EntryPoint」(Controller, Command)のみDIすることが出来る ・View, Helper,
Table, Mailer, Behaviorは出来ない(アプリケーション層から遠くDIする難易度が高いため) ・DIコンテナの持つ自由度とCakePHPの持つ制約を両立させた? 実際に試してみよう!
▪DIコンテナを利用したCakePHPの依存管理(サービス)
▪DIコンテナを使用したCakePHPの依存管理(DIコンテナ)
▪DIコンテナを使用したCakePHPの依存管理(コントローラー)
ここまでのまとめ ・CakePHPはこれまでサービスロケーター的な手法のみを採用してきた ・4.2系からDIコンテナを導入! ・DIコンテナ自体は比較的簡単に取り入れることが出来る ・サービスクラスを含めた設計の難しさは当然存在する
DIコンテナが導入される意味を考える Think about adding a DI Container
改めて、CakePHPの特徴 ・RailsライクなシンプルなMVCフレームワーク ・CoC(設定より規約)を重視 ・Pros: チーム開発において「縛り」が効果的、どの案件でも似た構成でスキルのポータビリティ性が高い ・Cons: 「Cake Way」を学ぶイニシャルコスト、「Cake Way」をはみ出すと途端に苦しくなる ・「90%の解を目指す」(UNIXの哲学)
・密結合で速く走るためのフレームワーク ・Laravelのような自由度や柔軟性はない≒Fatなビジネス要件に対処することが相対的に難しい ・しかし、(いわゆるWeb系の世界では)シンプルなMVCの構成で十分なことが多い
改めて、CakePHPの特徴 ・RailsライクなシンプルなMVCフレームワーク ・CoC(設定より規約)を重視 ・Pros: チーム開発において「縛り」が効果的、どの案件でも似た構成でスキルのポータビリティ性が高い ・Cons: 「Cake Way」を学ぶイニシャルコスト、「Cake Way」をはみ出すと途端に苦しくなる ・「90%の解を目指す」(UNIXの哲学)
・密結合で速く走るためのフレームワーク ・Laravelのような自由度や柔軟性はない≒Fatなビジネス要件に対処することが相対的に難しい ・しかし、(いわゆるWeb系の世界では)シンプルなMVCの構成で十分なことが多い 本当にそうなのか?
CakePHPの歴史と周辺技術の変遷 CakePHP 1.x~ CakePHP 2.x CakePHP 3.x~ CakePHP 4.x~ 2011
2006 2015 2019 PHP 7.x~ PHP 8.x~ PHP 5.3.x~ PHP ~5.3.x Web 2.0 PHP ~5.0 2004 Microservices Ajax Laravel Hack BFF GraphQL スマートフォンアプリ jQuery アフターデジタル X-Tech Composer SoR / SoE C10K PHP-FIG HTML5 Zend Framework Xdebug 2.0 PSR-0 PSR-1, 2 PSR-7 PSR-11 PSR-15 React REST ※時系列は正確ではありません(あくまで流れを掴む程度にご利用ください) ※当然ながら、全てを網羅しているわけでもありません(例: クラウド、IoTなど) Serverless
時代の流れ ・ここ10年ぐらいでソフトウェア開発は高度複雑化している ・技術のコモディティ化や抽象化が進み、敷居は下がったが「フルスタック」であることの難易度は上がった ・技術そのものの進化とソフトウェアが適用される分野が増えた ・ここ数年で「90%の解」が「80%」しか得られなくなってきた感覚がある ・この感覚自体は個人の感想ですが、昨今「SOLID」なフレームワークが求められているのは間違いない ・その失われた10%を取り戻すのが今回のDIコンテナの導入ではないか? ・Issueでも開発者のための機能と明言されている: https://github.com/cakephp/cakephp/issues/14865
今後どうなるのか? ・今の仕組み(サービスロケーター的な手法)を置き換えなかった ・あくまで実験的な機能としている ・CakePHPの思想を優先し、アドオン的な機能に留めた? ・アーキテクチャ観点で一定揺り戻しがあると考えた? ・Smart UIパターンが再評価される世界: https://onk.hatenablog.jp/entry/2020/11/11/024531
今後どうなるのか? ・今の仕組み(サービスロケーター的な手法)を置き換えなかった ・あくまで実験的な機能としている ・CakePHPの思想を優先し、アドオン的な機能に留めた? ・アーキテクチャ観点で一定揺り戻しがあると考えた? ・Smart UIパターンが再評価される世界: https://onk.hatenablog.jp/entry/2020/11/11/024531 分からない/(^o^)\
その上で、出来ること ・フレームワークを骨の髄まで味わい尽くす! ・開発効率を高めるには、フレームワークが持つポテンシャルを120%引き出す必要がある ・CakePHPに限った話ではないが、「CoC」系のフレームワークでは特に重要だと思う ・まずは、積極的にDIコンテナを使ってみる! ・公式がDIコンテナをサポートした意義は少なくない ・恐らく、最初はDIコンテナとComponentの使い分けのプラクティスを整理するところからかな…? ・そして、その結果をコミュニティへフィードバックする!
その上で、出来ること ・フレームワークを骨の髄まで味わい尽くす! ・開発効率を高めるには、フレームワークが持つポテンシャルを120%引き出す必要がある ・CakePHPに限った話ではないが、「CoC」系のフレームワークでは特に重要だと思う ・まずは、積極的にDIコンテナを使ってみる! ・公式がDIコンテナをサポートした意義は少なくない ・恐らく、最初はDIコンテナとComponentの使い分けのプラクティスを整理するところからかな…? ・そして、その結果をコミュニティへフィードバックする! ・未来を予測する最善の方法は、それを発明することだ(by アラン・ケイ氏)
よりよいソフトウェアを追求する旅路は続く…
まとめ tl;dr
今北産業 DIとDIコンテナについての概要 ・DIはソフトウェアを密結合から疎結合にする手法 ・DIコンテナはDI対象となるオブジェクトの管理を一箇所にまとめた箱 CakePHPに新しく導入されるDIコンテナの使い方 ・CakePHP4.2系から実験的にDIコンテナを導入! ・DIコンテナ自体は比較的簡単に取り入れることが出来る DIコンテナがCakePHPに導入される意味 ・変化する時代の中で「失われた10%の解」を取り戻すための打ち手の一つ(なのでは?) ・進化を遂げたCakePHPの今後に期待!1エンジニアとしてもその進化に貢献していきたい!
参考資料1/2 【DI / DIコンテナの理解を深めるために参考にさせていただいたみなさん】 ・Inversion of ControlコンテナとDependency Injectionパターン: https://kakutani.com/trans/fowler/injection.html ・Google/Guice(DIコンテナ)のモチベーション:
https://github.com/google/guice/wiki/Motivation ・History of Dependency Injection (DI): https://yauritux.wordpress.com/2011/04/03/history-of-dependency-injection-di/ ・何故DIコンテナが必要なのか: https://qiita.com/kabosu3d/items/200d14c68b8c0e5b2092 ・IoCとService LocatorとDIの関係: https://yotiky.hatenablog.com/entry/2018/09/28/IoCとService_LocatorとDIの関係 ・やはりあなた方のDependency Injectionはまちがっている。 http://blog.a-way-out.net/blog/2015/08/31/your-dependency-injection-is-wrong-as-I-expected/ 【アーキテクチャの変遷の理解を深めるために参考にさせていただいたみなさん】 ・Smart UI パターンが再評価される世界: https://onk.hatenablog.jp/entry/2020/11/11/024531 ・JetBrainsのPHP25周年インフォグラフィック: https://www.jetbrains.com/ja-jp/lp/php-25/
参考資料2/2 【CakePHPの理解を深めるために参考にさせていただいたみなさん】 ・CakePHPにDIコンテナが入った(る)と聞いて見学に行ってきました: https://daisuki.nichiyoubi.land/entry/cakephp-feature-di ・PSR-11対応のDIコンテナをCakePHP3で使う: https://nextat.co.jp/staff/archives/234 【CakePHP公式情報のみなさん】 ・DIコンテナについてのIssue: https://github.com/cakephp/cakephp/issues/14865 ・DIの使い方をまとめたドキュメント:
https://book.cakephp.org/4.next/en/development/dependency-injection.html ・Lead DeveloperであるMark Story氏の発表資料: https://www.slideshare.net/markstory/dependency-injection-in-cakephp
おまけ Additional Time
最後に宣伝です!
与太話 ・尻切れトンボを防ぐために、宣伝を本編の外部から注入しました ・これを登壇における「制御の反転」と言います(言いません)
会社紹介 ・「あなたの家族像が実現できる社会をつくる」というビジョンを掲げ、 ママの3人に1人(※) が利用する「ママリ」などを運営しています。 ・12月1日にロゴを含めた会社のリブランディングを発表しました! ※:「ママリ」で2019年内に出産予定と設定したユーザー数と、厚生労働省発表「人口動態統計」の出生数から算出。
エンジニア向けのミートアップイベントやります! ・12/17(木)19:30〜21:00 ・https://connehito.connpass.com/event/197332/ ・サービス開発の悩みをぶっちゃける会 ・例: ぶっちゃけ上手くいかなかった施策は? ・オンライン開催ですが、みんなでわいわい話す場になります! ・サービス開発に興味があれば誰でもOK! ・もちろん、コネヒトに興味がある人でもOK! ・先日公開した「Connehito
Tech Vision」についても話します ・https://connehito.com/recruit/tech/
ご清聴ありがとうございました!