laravel で学ぶMVC
株式会社chatbox
みかかね@mkkn_info
KFUG 年忘れLT大会
http://kfug.connpass.com/event/22377/
2015.12.13
about me
みかかね@mkkn_info
#PHPer, フロントエンド
# 株式会社chatbox 代表
#関西フロントエンドUG代表
関西でWeb制作とかやっています。
03/05にFRONTEND CONFERENCE 2016
開催します。
facebook:後藤知宏
twitter: @mkkn_info
laravel
この頃流行りのフレームワーク
laravel
開発が盛んなPHP製フレームワーク
コミュニティ等でも人気が高い
Symfonyベースのコンポーネントシステム・DI
使いやすさを重視した柔軟なUI
日本語リファレンスのほか、
最近は本も出てますます学びやすく。
とにかく人気
laravelの豊富な機能
• 認証
• キュー管理
• DBマイグレーション
• Tack / Schedule管理
• Billing
• etc…
lumenという派生の
マイクロフレームワークも
ミニマルな構成
+
豊富な機能パッケージ
他人と同じものを使うというのは
それだけでメリットだったり
本日はMVCのお話
Model View Controller
Webアプリケーション構築の考え方の1つ
ロジックを扱うモデル、見た目に関する処理をするView、
制御系のControllerの3層に分割する。
アプリケーションをModel View Controllerの3階層に分ける
膨大なシステムの分割手法の1つ
という、教科書的な話を聞いても
実際の現場ではよくわからない事が多かったり。
分割分割というけど、何のために?
なんとなくでMVCしてませんか?
MVCの目的と役割を理解して
正しいシステム分割を!!
laravel ≠ MVCフレームワーク
laravel = MVCもできるフレームワーク
Dispatch
いわゆるルーティング。MVCの前段階のレイヤ
route.php を利用してなんでも出来る。
フレームワークの重要な機能として、
リクエスト処理に応じて、処理を振り分ける機能
MVCディレクトリ構造を無視した
柔軟なルーティング設定が可能な点があげられる。
( 非常に重要!! )
MVCという概念の無いコード
<?php
// routes.php
Route::get('/top', function ()
{
$mode = Request::get("list_mode");
$list = Master_List::get($mode);
return view("top",["list"=>$list]);
});
1つのファイルに全てを収めるのは
管理が大変
だが、しかし
ファイルを分割するだけで
システムは便利になるのだろうか…
ファイル分割のデメリット
• 分散するコード
• 障害復旧の探索コスト
• 追加実装時に実装箇所で迷う
• etc…
システム分割の基本
基本的な目的は責務の明確化
責務の明確でないファイル分割は、
無駄にコードが分散して、逆に複雑になりがち。
ファイルを分ける事がシステム分割ではない。
ファイル毎にやること・やらないことを明確にする。
逆に1枚もののPHPでもブロックごとに責務が明確であれば、
十分に可読性のあるコードが出来上がる。
ファイルを分割しようとしない
責務を分割する
(結果としてファイルが分かれる)
Controller Model View
Request 扱う 扱わない 扱わない
ロジック 扱わない 扱う 扱わない
HTML 扱わない 扱わない 扱う
Controller の責務
Request (HTTP)を扱う責務
RequestをCに集約する(ロジックがHTTPを意識しない)と、
View層、Model層の再利用性が上がる。
Request = パラメータの処理や、Sessionなど
HTTP固有の処理
HTTPがController層に集約されると、
View層、Model層のテスト可能性が高まる。
Controller層を
View・Modelから分離することが
一番重要
スキニーコントローラの実践は簡単
Controllerでやるべきことを考える
Controller(層)ですべきこと
• Requestの処理
• Sessionの管理
• バリデーション
• エラーハンドリング
• ( 諸説あります )
Viewの責務
見た目に関する処理を扱う責務
何をするか(ロジック)と何を返すか(レスポンス)を
明確に分離することで、仕様変更に対する柔軟性が上がる。
一般的にはHTMLだが、APIなどの場合にはJSON
Responseとして捉えると良い。
一般的にロジックの修正は入りにくい。
レスポンスに関する修正は頻繁に発生する。
ポイント:ViewでControllerを扱わない
Controller 層を含むView
<div id=“header”>
<?php if($user = Auth::user()):?>
username: <?=$user->name?>
<?php endif;?>
</div>
<?php if($msg = Session::get(“message”)):?>
<div class=“alert alert-default”>
<?= $msg ?>
</div>
<?php endif; ?>
Viewで気をつけること
• データの割当は極力変数で割り当てる。
• テンプレート内部で呼び出すのは
ステートレスなヘルパー系の関数のみ
• ロジック的な複雑な処理は、
ステートレスにして、Modelに追い出す。
見た目に特化したViewのメリット
• Viewの中にロジックが入らないので
コードの見通しが良くなる。
• HTTPレベルの要件に依存しないので、
セッション等リクエスト層での仕様変更で
Viewを調査・変更する必要が無くなる。
• リクエストの状態に影響されないので、
Viewを部分的に切り出して転用も楽。
Modelの責務
ロジックに関する処理を扱う責務
機能に関するベースの部分で、テストの重要性が高い
設計においても比較的初期に仕様が固められる
ロジック = システムの根幹機能に関する処理全般
システムUIに関する影響を受けない根底部分
ロジックと言っても範囲は広範なため、
更に細かくレイヤを分割する必要がある。
ポイント1:ModelでControllerを扱わない
Controller 層を含むModel
public function login(){
$email = Request::get(“email”);
$password = Request::get(“password”);
$user = User::where([
“email” => $email ........
public function getUser(){
$id = Session::get(“login_id”);
return User::get($id);
}
ポイント2:ModelでViewを扱わない
View 層を含むModel
public function getUserJson(){
$data = $this->toArray();
unset($data[“passowrd”]); // パスワードはマスク
return $data;
}
public function getCategory(){
if($this->category){
return “<span class=‘category’>{$this->category}</span>”
}else{
return “<span class=‘default’>未分類</span>”
}
}
Modelで気をつけること
• Modelの入出力について、特定のケースのみを想定し
た書き方をしない。
• 入力:HTTPだけでなく Artisan,Jobなど
• 出力:HTMLだけでなくconsole, jsonなど
• 単純に引数と戻り値のみ考えれば良い。
• どうしても…という場合にはControllerServiceや
ViewModelといった層の導入も考えてみる。
ロジックに特化したModelのメリット
• Modelの責務が明確で仕様変更に強いModel
が出来上がる。
• 入出力が明確で、再利用性の高い柔軟なモデ
ルが出来上がる。
• 再利用性が高く、仕様変更にも強いためテス
トを書いても寿命が長く使える。
ユニットテストの導入は、
現場の状況次第で難易度が変わる
テスト可能なコードを書く
= 本人の技術力次第
テスト可能なコード
= 責務が明確であるコード
責務を意識してコード記述を進めると
ドメイン駆動などの設計論もわかりやすい
なんとなくでなぞると
「っぽい」だけで意図のわからないコードが…
責務意識して綺麗なMVC
ご清澄ありがとうございました。

〜laravel で学ぶ MVC