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
DIコンテナを学ぶ
Search
hihats
December 26, 2016
Technology
2
400
DIコンテナを学ぶ
PHPフレームワークのLaravelを通して、DIコンテナについて学習します
hihats
December 26, 2016
Tweet
Share
More Decks by hihats
See All by hihats
Which Json Serializer should we use in Ruby on Rails6 era
hihats
1
130
ソフトウェア設計についての基本認識
hihats
1
96
アジャイル開発を始める前におさえておきたいこと
hihats
0
110
AWS Lambdaの今現在
hihats
0
800
コードの静的解析ツールを使う目的と効用
hihats
0
250
Laravel勉強会 2016
hihats
0
1.5k
Other Decks in Technology
See All in Technology
仕様書駆動AI開発の実践: Issue→Skill→PRテンプレで 再現性を作る
knishioka
2
680
レガシー共有バッチ基盤への挑戦 - SREドリブンなリアーキテクチャリングの取り組み
tatsukoni
0
220
Agent Skils
dip_tech
PRO
0
120
小さく始めるBCP ― 多プロダクト環境で始める最初の一歩
kekke_n
1
450
データの整合性を保ちたいだけなんだ
shoheimitani
8
3.2k
Context Engineeringが企業で不可欠になる理由
hirosatogamo
PRO
3
620
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
15
93k
超初心者からでも大丈夫!オープンソース半導体の楽しみ方〜今こそ!オレオレチップをつくろう〜
keropiyo
0
110
2026年、サーバーレスの現在地 -「制約と戦う技術」から「当たり前の実行基盤」へ- /serverless2026
slsops
2
260
こんなところでも(地味に)活躍するImage Modeさんを知ってるかい?- Image Mode for OpenShift -
tsukaman
1
160
20260208_第66回 コンピュータビジョン勉強会
keiichiito1978
0
180
ブロックテーマ、WordPress でウェブサイトをつくるということ / 2026.02.07 Gifu WordPress Meetup
torounit
0
190
Featured
See All Featured
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
230
The Pragmatic Product Professional
lauravandoore
37
7.1k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
97
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
150
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
359
30k
How to Think Like a Performance Engineer
csswizardry
28
2.4k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
180
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
190
Testing 201, or: Great Expectations
jmmastey
46
8k
Technical Leadership for Architectural Decision Making
baasie
2
250
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.3k
Transcript
DIコンテナを学ぶ Laravelの肝
このDIコンテナ(サービスコンテナ)を学びましょう • LaravelではDIコンテナという仕組みを使用しており、そこで依存性の解決 を行っています。 • リファレンス本の中でサービスコンテナと書いてあるものが、DIコンテナに 当たります。 • コントローラーに依存関係を持たせなくてよくなるため、コントローラーの 単体テストが容易になったりします。
• bootstrap/app.php の中で返される $app がサービスコンテナそのもの です。 Laravelを使い始める前にまず
しかし、まずその前に
DIとは? 依存性とは? コントローラー とは? MVCとは? 前提知識も足りていないことが多い そもそも、フレームワークを使う上 での基本からおさらい しときま しょう
処理フローを学ぶためにフレーム ワークを使う場合と使わない場合の 違いから入っていきます
FW使わない場合 ブラウザで http://localhost:8080/get_user.php?uid=3 public/index.php public/get_user.php public/login.php ・・・・・ fileひとつで処理が完結するpattern
FW使う場合 Entrypointが入り口の全てを引き受ける public/index.phpがEntrypointに当たる (Laravel含め多くのPHPフレームワークで) 全てのアクセスがindex.phpを呼び出し、リクエスト内容(URL)から各コント ローラーに振り分けられる
コンポーネント基礎構造 ⑤ビジネスロジック ④コントローラー ③ Router ① Request ⑥ ビュー ⑦
Response Laravelも MVC パターンっぽくは見える が、Modelがない 元々はModelsディレクトリが存在してい たが、5.1からなくなる 既存の曖昧な「モデル」という表現を使う ことによるの弊害をなくしたかった もっと限定された語彙を使用し開発を行えば、明確 に定義された責任を持つ、より小さくてきれいなクラ スへ、アプリケーションを簡単に分割できるでしょう by Taylor Otwell
コンポーネント基礎構造 ⑤ビジネスロジック ④コントローラー ③ Router ① Request ⑥ ビュー ⑦
Response Laravelも MVC パターンっぽくは見える が、Modelがない 元々はModelsディレクトリが存在してい たが、5.1からなくなる 既存の曖昧な「モデル」という表現を使う ことによるの弊害をなくしたかった ② Middleware もっと限定された語彙を使用し開発を行えば、明確 に定義された責任を持つ、より小さくてきれいなク ラスへ、アプリケーションを簡単に分割できるでしょ う by Taylor Otwell
つまり
Model(らしきもの)をどう設計、実装するか は我々に委ねられている
なので
Modelはいったん置いときましょう 設計思想や経験に基づき、各ユーザごとに様々なモデリングが行われている あまりにも理解のための幅が広く、難易度が高い その代わり、コントローラとビューについては、標準で設置されており、役割も定められているので、ここか ら理解していくのがよい (Laravelにおいては)
Controller の責務 ・ユーザからの入力を受け取る ・ビューを選択、生成する この二つだけ Sample(製品モデルを扱うコントローラ) app/Http/Controllers/ProductController.php をみてみる
<?php namespace App\Http\Controllers; use Product; class ProductController extends Controller {
/** * ProductController constructor. */ public function __construct() { } //一覧 public function index() { $id = request()->get(‘id’); $product = new Product(); $products = $product->find($id); return view('product.index, array('products' => $products)); } } app/Http/Controllers/ProductController.php
<?php namespace App\Http\Controllers; use Product; class ProductController extends Controller {
/** * ProductController constructor. */ public function __construct() { } //一覧 public function index() { $id = request()->get(‘id’); $product = new Product(); $products = $product->find($id); return view('product.index, array('products' => $products)); } } app/Http/Controllers/ProductController.php 入力を受けとり ビューを生成
ここから依存性の話
<?php namespace App\Http\Controllers; use Product; class ProductController extends Controller {
/** * ProductController constructor. */ public function __construct() { } //一覧 public function index() { $id = request()->get(‘id’); $product = new Product(); $products = $product->find($id); return view('product.index, array('products' => $products)); } } app/Http/Controllers/ProductController.php
Object(コントローラー)がObject()に依存し ている
<?php namespace App\Http\Controllers; use Product; class ProductController extends Controller {
/** * ProductController constructor. */ public function __construct() { } //一覧 public function index() { $id = request()->get(‘id’); $product = new Product(); $products = $product->find($id); return view('product.index, array('products' => $products)); } } app/Http/Controllers/ProductController.php
<?php namespace App\Http\Controllers; use Product; class ProductController extends Controller {
/** * ProductController constructor. */ public function __construct() { } //一覧 public function index() { $id = request()->get(‘id’); $product = new Product(‘has_option’); $products = $product->find($id); return view('product.index, array('products' => $products)); } } app/Http/Controllers/ProductController.php
<?php namespace App\Http\Controllers; use Product; class ProductController extends Controller {
/** * ProductController constructor. */ public function __construct() { } //一覧 public function index(Product $product) { $id = request()->get(‘id’); $products = $product->find($id); return view('product.index, compact('products')); } } $product = new Product(); $product = new Product(‘has_option’); app/Http/Controllers/ProductController.php どちらも使える
依存されているObjectを外から引数で渡すことを 「依存性の注入(Dependency Injection)」という
これがDI(パターン)
ちなみにLaravelでは、外でnewしなくても、タイプヒン ティングで勝手にインスタンス生成してくれる(条件 つき)
結合を緩くする(疎結合)
/** * Productインターフェースとそれを実装したクラスを1ファイルにまとめたもの */ interface ProductInterface { public function __construct()
{ } } class PackageProduct implements ProductInterface { public function __construct() { } } class CloudProduct implements ProductInterface { public function __construct() { } } } ProductInterfaceを実装し た、具象クラスが二つ
<?php namespace App\Http\Controllers; use Product; class ProductController extends Controller {
/** * ProductController constructor. */ public function __construct() { } //一覧 public function index(ProductInterface $product) { $id = request()->get(‘id’); $products = $product->find($id); return view('product.index, compact('products')); } } 抽象に注入せよ (OODのDI原則)
<?php namespace App\Http\Controllers; use Product; class ProductController extends Controller {
/** * ProductController constructor. */ public function __construct(Product $product) { $this->product = $product; } //一覧 public function index() { $id = request()->get(‘id’); $products = $this->product->find($id); return view('product.index, compact('products')); } } コンストラクタ インジェクション
<?php namespace App\Http\Controllers; use Product; class ProductController extends Controller {
/** * ProductController constructor. */ public function __construct(Product $product) { $this->product = $product; $this->request = request(); } //一覧 public function index() { $id = $this->request->get(‘id’); $products = $this->product->find($id); return view('product.index, compact('products')); } } =Request::class
依存性がどんどん複雑になってくる
依存を再帰的に解決するなど、複雑な依存関係の 解決を一手に引き受けてくれるのが
DIコンテナ(サービスコンテナ)
まとめ
• コントローラーに責務を追わせすぎないようにしましょう • オブジェクト同士の依存性をできるだけ緩くしましょう(疎結合) • 依存関係がソースコードの奥深くに入り込まないように、DIコンテナに解決 を任せましょう