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
製造業からパッケージ製品まで、あらゆる領域をカバー!生成AIを利用したテストシナリオ生成 / 20250627 Suguru Ishii
shift_evolve
PRO
1
160
250627 関西Ruby会議08 前夜祭 RejectKaigi「DJ on Ruby Ver.0.1」
msykd
PRO
2
370
Delegating the chores of authenticating users to Keycloak
ahus1
0
130
強化されたAmazon Location Serviceによる新機能と開発者体験
dayjournal
3
260
MUITにおける開発プロセスモダナイズの取り組みと開発生産性可視化の取り組みについて / Modernize the Development Process and Visualize Development Productivity at MUIT
muit
0
770
解析の定理証明実践@Lean 4
dec9ue
1
200
「Chatwork」の認証基盤の移行とログ活用によるプロダクト改善
kubell_hr
1
240
FOSS4G 2025 KANSAI QGISで点群データをいろいろしてみた
kou_kita
0
290
How Community Opened Global Doors
hiroramos4
PRO
1
130
論文紹介:LLMDet (CVPR2025 Highlight)
tattaka
0
240
生成AIで小説を書くためにプロンプトの制約や原則について学ぶ / prompt-engineering-for-ai-fiction
nwiizo
4
3.7k
fukabori.fm 出張版: 売上高617億円と高稼働率を陰で支えた社内ツール開発のあれこれ話 / 20250704 Yoshimasa Iwase & Tomoo Morikawa
shift_evolve
PRO
1
450
Featured
See All Featured
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
657
60k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.7k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Speed Design
sergeychernyshev
32
1k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
107
19k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.4k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
How to Ace a Technical Interview
jacobian
277
23k
Balancing Empowerment & Direction
lara
1
400
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
Designing for Performance
lara
609
69k
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コンテナに解決 を任せましょう