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
120
ソフトウェア設計についての基本認識
hihats
1
87
アジャイル開発を始める前におさえておきたいこと
hihats
0
110
AWS Lambdaの今現在
hihats
0
800
コードの静的解析ツールを使う目的と効用
hihats
0
240
Laravel勉強会 2016
hihats
0
1.4k
Other Decks in Technology
See All in Technology
Claude Code でアプリ開発をオートパイロットにするためのTips集 Zennの場合 / Claude Code Tips in Zenn
wadayusuke
3
230
エンジニアリングマネージャーの成長の道筋とキャリア / Developers Summit 2025 KANSAI
daiksy
2
580
バイブスに「型」を!Kent Beckに学ぶ、AI時代のテスト駆動開発
amixedcolor
2
580
AIエージェントで90秒の広告動画を制作!台本・音声・映像・編集をつなぐAWS最新アーキテクチャの実践
nasuvitz
3
330
CDK CLIで使ってたあの機能、CDK Toolkit Libraryではどうやるの?
smt7174
4
190
要件定義・デザインフェーズでもAIを活用して、コミュニケーションの密度を高める
kazukihayase
0
120
スクラムガイドに載っていないスクラムのはじめかた - チームでスクラムをはじめるときに知っておきたい勘所を集めてみました! - / How to start Scrum that is not written in the Scrum Guide 2nd
takaking22
1
120
新アイテムをどう使っていくか?みんなであーだこーだ言ってみよう / 20250911-rpi-jam-tokyo
akkiesoft
0
320
Modern Linux
oracle4engineer
PRO
0
150
「何となくテストする」を卒業するためにプロダクトが動く仕組みを理解しよう
kawabeaver
0
420
まずはマネコンでちゃちゃっと作ってから、それをCDKにしてみよか。
yamada_r
2
120
「全員プロダクトマネージャー」を実現する、Cursorによる仕様検討の自動運転
applism118
22
12k
Featured
See All Featured
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
31
2.2k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.1k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
580
Documentation Writing (for coders)
carmenintech
74
5k
The Language of Interfaces
destraynor
161
25k
Building Applications with DynamoDB
mza
96
6.6k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.9k
Large-scale JavaScript Application Architecture
addyosmani
513
110k
BBQ
matthewcrist
89
9.8k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.1k
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コンテナに解決 を任せましょう