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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
hihats
December 26, 2016
Technology
410
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
DIコンテナを学ぶ
PHPフレームワークのLaravelを通して、DIコンテナについて学習します
hihats
December 26, 2016
More Decks by hihats
See All by hihats
Which Json Serializer should we use in Ruby on Rails6 era
hihats
1
140
ソフトウェア設計についての基本認識
hihats
1
110
アジャイル開発を始める前におさえておきたいこと
hihats
0
120
AWS Lambdaの今現在
hihats
0
810
コードの静的解析ツールを使う目的と効用
hihats
0
260
Laravel勉強会 2016
hihats
0
1.5k
Other Decks in Technology
See All in Technology
新規ゲーム開発におけるAI駆動開発のリアル
202409e2
0
2.9k
実装は速くなった、レビューはどうする? ― 自身のレビューをAIで再現させるサーヴァントエンジニアリングのすゝめ / Implementation got faster. So what about reviews? — An invitation to Servant Engineering: Recreating your own code reviews with AI
nrslib
7
4.2k
AI Adaptable なテストを整える工夫 / Ways to Make Your Tests AI-Adaptable
bitkey
PRO
3
220
「コーディング」しない人のための Claude Code 入門 ChatGPT の次の一歩 — 業務に組み込む 育成・共有・自動化
rfdnxbro
2
1.2k
価格.comをAI駆動で全面刷新する ー 30年分の技術的負債を返し、次の30年の土台をつくる ー / AI Engineering Summit Tokyo 2026
tkyowa
50
56k
AI-DLCを活用した高品質・安全なAI駆動開発実践 / AI Driven Development
yoshidashingo
1
380
PHP と TypeScript の型システム比較:AI 時代の「型」は誰のためにあるのか? #frontend_phpcon_do / frontend_phpcon_do_2026
shogogg
1
260
Agentic Web
dynamis
1
180
【Gen-AX】20260530開催_JJUG CCC 2026 Spring
genax
0
440
作って終わりにしない タイミーのセマンティックレイヤー育成の現在地
chanyou0311
0
270
Claude Code×Terraform IaC テンプレート駆動開発
itouhi
1
430
BigQuery の Cross-cloud Lakehouse への歩み
phaya72
2
600
Featured
See All Featured
The SEO Collaboration Effect
kristinabergwall1
1
480
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
130
Odyssey Design
rkendrick25
PRO
2
690
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.2k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.8k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.2k
Principles of Awesome APIs and How to Build Them.
keavy
128
17k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.9k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
What's in a price? How to price your products and services
michaelherold
247
13k
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コンテナに解決 を任せましょう