SlideShare a Scribd company logo
1 of 34
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 AppHttpControllers;
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 AppHttpControllers;
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 AppHttpControllers;
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 AppHttpControllers;
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 AppHttpControllers;
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 AppHttpControllers;
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 AppHttpControllers;
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 AppHttpControllers;
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 AppHttpControllers;
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コンテナ
に解決を任せましょう

More Related Content

Similar to Diコンテナを学ぶ

T35 ASP.NET MVCを使ったTDD入門
T35 ASP.NET MVCを使ったTDD入門T35 ASP.NET MVCを使ったTDD入門
T35 ASP.NET MVCを使ったTDD入門normalian
 
C# コーディングガイドライン 2013/02/26
C# コーディングガイドライン 2013/02/26C# コーディングガイドライン 2013/02/26
C# コーディングガイドライン 2013/02/26Yoshihisa Ozaki
 
スキトラ Spring + mybatis
スキトラ Spring + mybatisスキトラ Spring + mybatis
スキトラ Spring + mybatis小川 昌吾
 
DevOpsのはじめの一歩 〜監視の変遷〜
DevOpsのはじめの一歩 〜監視の変遷〜DevOpsのはじめの一歩 〜監視の変遷〜
DevOpsのはじめの一歩 〜監視の変遷〜Akihiro Kuwano
 
ASP.NET WEB API 開発体験
ASP.NET WEB API 開発体験ASP.NET WEB API 開発体験
ASP.NET WEB API 開発体験miso- soup3
 
やはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているやはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているKoichi Tanaka
 
Application Architecture for Enterprise Win Store Apps with DDD Pattern
Application Architecture for Enterprise Win Store Apps with DDD PatternApplication Architecture for Enterprise Win Store Apps with DDD Pattern
Application Architecture for Enterprise Win Store Apps with DDD PatternAtsushi Kambara
 
Cloud Foundry構成概要 111018
Cloud Foundry構成概要 111018Cloud Foundry構成概要 111018
Cloud Foundry構成概要 111018Uemura Yuichi
 
Visual Studio Onlineで実践するDevOps手法
Visual Studio Onlineで実践するDevOps手法Visual Studio Onlineで実践するDevOps手法
Visual Studio Onlineで実践するDevOps手法Takashi Takebayashi
 

Similar to Diコンテナを学ぶ (10)

T35 ASP.NET MVCを使ったTDD入門
T35 ASP.NET MVCを使ったTDD入門T35 ASP.NET MVCを使ったTDD入門
T35 ASP.NET MVCを使ったTDD入門
 
C# コーディングガイドライン 2013/02/26
C# コーディングガイドライン 2013/02/26C# コーディングガイドライン 2013/02/26
C# コーディングガイドライン 2013/02/26
 
スキトラ Spring + mybatis
スキトラ Spring + mybatisスキトラ Spring + mybatis
スキトラ Spring + mybatis
 
DevOpsのはじめの一歩 〜監視の変遷〜
DevOpsのはじめの一歩 〜監視の変遷〜DevOpsのはじめの一歩 〜監視の変遷〜
DevOpsのはじめの一歩 〜監視の変遷〜
 
ASP.NET WEB API 開発体験
ASP.NET WEB API 開発体験ASP.NET WEB API 開発体験
ASP.NET WEB API 開発体験
 
やはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているやはりお前らのMVCは間違っている
やはりお前らのMVCは間違っている
 
転職とLaravel
転職とLaravel転職とLaravel
転職とLaravel
 
Application Architecture for Enterprise Win Store Apps with DDD Pattern
Application Architecture for Enterprise Win Store Apps with DDD PatternApplication Architecture for Enterprise Win Store Apps with DDD Pattern
Application Architecture for Enterprise Win Store Apps with DDD Pattern
 
Cloud Foundry構成概要 111018
Cloud Foundry構成概要 111018Cloud Foundry構成概要 111018
Cloud Foundry構成概要 111018
 
Visual Studio Onlineで実践するDevOps手法
Visual Studio Onlineで実践するDevOps手法Visual Studio Onlineで実践するDevOps手法
Visual Studio Onlineで実践するDevOps手法
 

Diコンテナを学ぶ

Editor's Notes

  1. CodeCampなどで最初に学ぶやつ URLにファイル名を含める
  2. 本来はMiddlewareなども入ってくるが、今回は割愛する
  3. index()アクションなのに、詳細画面のロジックじゃない?ってのはスルーしてください
  4. index()アクションなのに、詳細画面のロジックじゃない?ってのはスルーしてください
  5. new Product() がないと、function index()は動かない = コントローラーが Productクラスに依存している
  6. この場合はメソッドインジェクション
  7. Interfaceは実装を書かない継承されるためのクラス
  8. オブジェクト指向設計にはSOLID原則という5つの原則があり、その中の「依存関係逆転の原則」がこれにあたる
  9. コンストラクタに渡す場合はコンストラクタインジェクション
  10. 例)コンストラクタの引数が両手で収まらない
  11. http://blog.tojiru.net/article/304867046.html