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
390
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
110
ソフトウェア設計についての基本認識
hihats
1
79
アジャイル開発を始める前におさえておきたいこと
hihats
0
100
AWS Lambdaの今現在
hihats
0
780
コードの静的解析ツールを使う目的と効用
hihats
0
220
Laravel勉強会 2016
hihats
0
1.4k
Other Decks in Technology
See All in Technology
コンテナ・K8s研修 - 前半 コンテナ基礎・ハンズオン【MIXI 24新卒技術研修】
mixi_engineers
PRO
0
170
What if...? 처음부터 다시 LLM 어플리케이션을 개발한다면
huffon
0
1k
サービス開発を前に進めるために 新米リードエンジニアが 取り組んだこと / Steps Taken by a Novice Lead Engineer to Advance Service Development
nologyance
0
180
技術負債による事業の失敗はなぜ起こるのか / Why do business failures due to technical debt occur?
i35_267
0
190
簡単に始めるSnowflakeの機械学習
nayuts
1
190
[NIKKEI Tech Talk] KDDI/KAG Scrum & Community for Engineering Training
curanosuke
2
220
コミュニティサービスに「あなたへ」フィードを リリースするまでの試行錯誤
takapy
1
150
クラウド利用者の「責任」をどう果たす?AWSセキュリティ対策のススメ #AWSSummit
hiashisan
0
280
Github Actions 로 Android 팀의 효율성 극대화
hadonghyun
0
160
ACRiルーム最新情報とAMD GPUサーバーのご紹介
anjn
0
160
AWSで”最小権限の原則”を実現するための考え方 /20240722-ssmjp-aws-least-privilege
opelab
10
4.4k
推薦システムを本番導入する上で一番優先すべきだったこと~NewsPicks記事推薦機能の改善事例を元に~
morinota
0
130
Featured
See All Featured
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
34
1.9k
The Brand Is Dead. Long Live the Brand.
mthomps
52
36k
Building Adaptive Systems
keathley
34
2k
For a Future-Friendly Web
brad_frost
173
9.2k
ParisWeb 2013: Learning to Love: Crash Course in Emotional UX Design
dotmariusz
105
6.8k
Atom: Resistance is Futile
akmur
261
25k
10 Git Anti Patterns You Should be Aware of
lemiorhan
652
58k
Facilitating Awesome Meetings
lara
46
5.8k
Unsuck your backbone
ammeep
666
57k
What the flash - Photography Introduction
edds
65
11k
How to train your dragon (web standard)
notwaldorf
79
5.5k
The Invisible Side of Design
smashingmag
294
50k
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コンテナに解決 を任せましょう