More Related Content
PDF
PHPコードではなく PHPコードの「書き方」を知る PDF
レイヤードアーキテクチャを意識したPHPアプリケーションの構築 PDF
Azure Websites で作るスケーラブルな PHP アプリケーション PDF
PDF
Laravel ユーザなら知っておくべきAuthオートログイン PDF
認証機能で学ぶ Laravel 5 アプリケーション PDF
Heroku で作る
スケーラブルな
PHP アプリケーション PDF
What's hot
PDF
Vagrant で作る PHP 開発環境 [実践編] PDF
PDF
Vagrant で PHP 開発環境を作る ハンズオン PDF
PDF
JavaScriptCore.framework の普通な使い方 #cocoa_kansai PDF
PDF
PDF
Isomorphic web development with scala and scala.js PDF
PDF
PDF
ビズリーチの新サービスをScalaで作ってみた 〜マイクロサービスの裏側 #jissenscala PDF
Scala が支える医療系ウェブサービス #jissenscala PDF
PPTX
PDF
CSS Preprocessor Hands-on PDF
Serverless frameworkでお手軽lambda運用 at #nseg #93 PPTX
Serverless frameworkを使ってみた話 at #nseg #90 PDF
PDF
RxSwiftのデータバインディングだけ PDF
Viewers also liked
PDF
PDF
東京から沖縄に移住したからこそわかるクラウドとコミュニティの有り難み 〜人はもっと自由になれる〜 PDF
PPTX
【ハンズオン】初めてのUnityで作る「3D野球盤」_"8a1"20150204発表資料 PDF
NetBeans、FuelPHP と過ごしたこの 2 ヶ月 KEY
Composer による依存管理 と Packagist によるライブラリの公開 PDF
Twilio を使えば簡単にできる アプリケーションと電話/SMS連携 PPTX
PSR-1 と PSR-2 を5分でざっくり理解する PDF
PDF
PDF
PDF
PDF
SwiftとReactNativeで似たようなUIを作った際の記録 PPTX
はじめて作ったアプリが10,000ダウンロード達成したから自慢する PDF
PDF
PPTX
20151205フルスクラッチcms作成のノウハウ With Laravel PDF
PPTX
PDF
MySQL・PostgreSQLだけで作る高速でリッチな全文検索システム Similar to レイヤードアーキテクチャを意識した PHPアプリケーションの構築 ver2
PDF
PDF
Isucon makers casual talks PDF
WTM53 phpフレームワーク いまさらcodeigniter PDF
PDF
PDF
PDF
PDF
PDF
20091030cakephphandson 02 PDF
PDF
KEY
PDF
PDF
PDF
スマートフォン向けサービスにおけるサーバサイド設計入門 KEY
PDF
10分でわかるFuelPHP @ 2012/05 OSC2012 Nagoya PPTX
More from Masashi Shinbara
PDF
PDF
PDF
PDF
How to learn Laravel5 application from Authentication PDF
PDF
PDF
PDF
PDF
PDF
もう XAMPP / MAMP はいらない!
Vagrant で作る PHP 開発環境 PDF
PDF
PDF
PDF
Kansai PHP Users Group 2012年活動報告 レイヤードアーキテクチャを意識した PHPアプリケーションの構築 ver2
- 1.
- 2.
- 3.
- 4.
- 5.
OSI参照モデル
(c) 2015 MasashiShinbara @shin1x1
7.Application
6. Presentation
5. Session
4.Transport
3. Network
2. Data link
1. Physical
- 6.
- 7.
- 8.
- 9.
Fat Model
(c) 2015Masashi Shinbara @shin1x1
• 1,000行を超える Model
• Model の役割が多すぎる
• DAO / バリデーション / ビジネスロジックなど
- 10.
- 11.
- 12.
- 13.
結果
(c) 2015 MasashiShinbara @shin1x1
• Fat(Controller¦Model) を、ある程度解消
• レイヤの責務があいまい
=> サービスが、セッションを操作等
• レイヤ間の処理の流れが統一できていない
=> サービスが、コントローラを操作等
- 14.
- 15.
Laravel
(c) 2015 MasashiShinbara @shin1x1
• Laraval + AngularJS
• Laravel は、REST API の提供のみ
• UI 関連の処理は、AngularJS
• レイヤの責務と流れを意識
- 16.
- 17.
レイヤの役割
(c) 2015 MasashiShinbara @shin1x1
Routing
Controller
ORM
Service
ルーティング、認証、フィルタ
HTTPリクエスト、レスポンス
バリデーション、サービス実行
事前条件検証、ビジネスロジック
データベースアクセス、
エンティティ固有の処理
- 18.
例: 書籍の予約
(c) 2015Masashi Shinbara @shin1x1
•会員制書籍予約Webアプリケーション
•利用者は認証トークンが必要
•書籍の予約を行う
•予約する書籍と予約数を指定
- 19.
例: 書籍の予約
(c) 2015Masashi Shinbara @shin1x1
•POST /reservation
•X-Api-Token: ユーザ認証トークン
•asin=書籍コード
•quantity=予約数
- 20.
- 21.
- 22.
- 23.
Controllerレイヤ
(c) 2015 MasashiShinbara @shin1x1
•POSTパラメータ、セッションユーザ情報を取得
•バリデーション実行
(asinとquantityパラメータの形式チェック)
•サービスに必要なパラメータを渡して実行
(HTTPの関心事はサービスに持ち込まない)
•HTTPレスポンスを返す
- 24.
Controller
public function create()
{
$validator= (new ReservationValidatorBuilder())->create(Input::all());
if ($validator->fails()) {
return $this->responseValidationError($validator->messages());
}
$reservation = $this->service->book($this->getUser(), Input::all());
return $this->responseCreated($reservation);
}
バリデーション
- 25.
Controller
public function create()
{
$validator= (new ReservationValidatorBuilder())->create(Input::all());
if ($validator->fails()) {
return $this->responseValidationError($validator->messages());
}
$reservation = $this->service->book($this->getUser(), Input::all());
return $this->responseCreated($reservation);
}
サービスの実行
- 26.
- 27.
Service
public function book(User$user, array $inputs)
{
$book = Book::where('asin', $inputs['asin'])->first();
if (empty($book)) {
throw new PreconditionException('book_not_found');
}
if ($book->inventory < $inputs['quantity']) {
throw new PreconditionException('not_enough_book_inventory');
}
$reservation = new Reservation();
DB::transaction(function () use ($user, $book, &$reservation, $inputs) {
$affectedRows = $book->decrementInventory($inputs['quantity']);
if ($affectedRows !== 1) {
throw new PreconditionException('not_enough_book_inventory');
}
$reservation->user_id = $user->id;
$reservation->book_id = $book->id;
$reservation->quantity = $inputs['quantity'];
$reservation->reservation_code = $reservation->generateReservationCode();
$reservation->save();
});
return $reservation;
}
- 28.
Service
public function book(User$user, array $inputs)
{
$book = Book::where('asin', $inputs['asin'])->first();
if (empty($book)) {
throw new PreconditionException('book_not_found');
}
if ($book->inventory < $inputs['quantity']) {
throw new PreconditionException('not_enough_book_inventory');
}
$reservation = new Reservation();
DB::transaction(function () use ($user, $book, &$reservation, $inputs) {
$affectedRows = $book->decrementInventory($inputs['quantity']);
if ($affectedRows !== 1) {
throw new PreconditionException('not_enough_book_inventory');
}
$reservation->user_id = $user->id;
$reservation->book_id = $book->id;
$reservation->quantity = $inputs['quantity'];
$reservation->reservation_code = $reservation->generateReservationCode();
$reservation->save();
});
return $reservation;
}
必要なパラメータ
- 29.
Service
public function book(User$user, array $inputs)
{
$book = Book::where('asin', $inputs['asin'])->first();
if (empty($book)) {
throw new PreconditionException('book_not_found');
}
if ($book->inventory < $inputs['quantity']) {
throw new PreconditionException('not_enough_book_inventory');
}
$reservation = new Reservation();
DB::transaction(function () use ($user, $book, &$reservation, $inputs) {
$affectedRows = $book->decrementInventory($inputs['quantity']);
if ($affectedRows !== 1) {
throw new PreconditionException('not_enough_book_inventory');
}
$reservation->user_id = $user->id;
$reservation->book_id = $book->id;
$reservation->quantity = $inputs['quantity'];
$reservation->reservation_code = $reservation->generateReservationCode();
$reservation->save();
});
return $reservation;
}
事前条件の検証
- 30.
Service
public function book(User$user, array $inputs)
{
$book = Book::where('asin', $inputs['asin'])->first();
if (empty($book)) {
throw new PreconditionException('book_not_found');
}
if ($book->inventory < $inputs['quantity']) {
throw new PreconditionException('not_enough_book_inventory');
}
$reservation = new Reservation();
DB::transaction(function () use ($user, $book, &$reservation, $inputs) {
$affectedRows = $book->decrementInventory($inputs['quantity']);
if ($affectedRows !== 1) {
throw new PreconditionException('not_enough_book_inventory');
}
$reservation->user_id = $user->id;
$reservation->book_id = $book->id;
$reservation->quantity = $inputs['quantity'];
$reservation->reservation_code = $reservation->generateReservationCode();
$reservation->save();
});
return $reservation;
}
ビジネスロジックの実行
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
結果
(c) 2015 MasashiShinbara @shin1x1
• レイヤの役割に専念できる
• 流れが一方向なので、依存の方向が明確に
• サービス(ドメイン)に集中
• サービスをどう分割していくかが課題
- 40.
- 41.