failure of cake php

43
CakePHP CakePHP のののの のののの ののののののののの のののののののののののの のののの 2008/6/27 1 BlueOcean

Upload: yokada

Post on 12-Jun-2015

4.964 views

Category:

Technology


7 download

TRANSCRIPT

Page 1: Failure Of Cake PHP

CakePHPCakePHP の失敗の失敗談談増えたのは残業時間

株式会社ブルーオーシャン岡田佳典

2008/6/27 1BlueOcean

Page 2: Failure Of Cake PHP

自己紹介自己紹介株式会社ブルーオーシャン

◦Web コンテンツの企画・開発・運営◦やっと事務所が借りられる

岡田佳典◦Web システム開発◦CakePHP 関連情報の執筆

2008/6/27 2BlueOcean

Page 3: Failure Of Cake PHP

発表の概要発表の概要CakePHP を使う中で遭遇した7つの失敗を次の観点から紹介します◦背景◦惨劇◦原因◦解決策

今後の開発にお役立てください

2008/6/27 3BlueOcean

Page 4: Failure Of Cake PHP

第1の失敗第1の失敗

AppController::beforeFilter() にログインチェックを書く

2008/6/27 4BlueOcean

Page 5: Failure Of Cake PHP

第1の失敗 第1の失敗 - - 背景背景ログインが必要なアプリケーションを作る必要があった

ほとんどのアクションでログインチェックが必要なため、コントローラごとにログインチェックを書きたくなかった

2008/6/27 5BlueOcean

Page 6: Failure Of Cake PHP

第1の失敗 第1の失敗 – – 惨劇惨劇ログインチェックが不要なアクションを指定できなければならなくなった◦たとえば PagesController の display アクションなど

◦しかも、頼りのコントローラ名とアクション名は空の場合がある

派生クラスで beforeFilter() を実装する場合に parent::beforeFilter() を呼ぶ必要が生じる

2008/6/27 6BlueOcean

Page 7: Failure Of Cake PHP

第1の失敗 第1の失敗 – – 失敗の原因失敗の原因AppController の beforeFilter() にログインチェックを書けば、すべての派生クラスでログインチェックを有効にできると手抜きをした

オブジェクト指向がもたらす効果がわかっていなかった

2008/6/27 7BlueOcean

Page 8: Failure Of Cake PHP

第1の失敗 第1の失敗 – – 解決策解決策CakePHP 1.2 の場合は Auth コンポーネントを使う

CakePHP 1.1 の場合でも同等のコンポーネントを作る

2008/6/27 8BlueOcean

Page 9: Failure Of Cake PHP

第1の失敗 第1の失敗 – – 解決策 解決策 – – 効果効果ログインチェックの有無をクラスの連携で設定できるようになる

意外とこのスタイルの方が保守しやすい

2008/6/27 9BlueOcean

Page 10: Failure Of Cake PHP

第2の失敗第2の失敗関連するモデルにアソシエーションを動的設定する

2008/6/27 10BlueOcean

Page 11: Failure Of Cake PHP

第2の失敗 第2の失敗 – – 背景背景多すぎるアソシエーションは重いという先入観から、必要に応じてアソシエーションを設定する方向性で開発していた◦bindModel()

2008/6/27 11BlueOcean

Page 12: Failure Of Cake PHP

第2の失敗 第2の失敗 – – 惨劇惨劇bindModel() を実行してもアソシエーションが変更されないという不具合に遭遇した◦User モデルが Review を hasMany している時、 Review と Vote を関連づけたい

◦×$this->Review->bindModel(“Vote”);

原因究明に時間がかかった

2008/6/27 12BlueOcean

Page 13: Failure Of Cake PHP

第2の失敗 第2の失敗 – – 失敗の原因失敗の原因CakePHP の仕様を理解していなかった

2008/6/27 13BlueOcean

Page 14: Failure Of Cake PHP

第2の失敗 第2の失敗 – – 解決策解決策$this->User->Review-

>bindModel(“Vote”) で解決した

2008/6/27 14BlueOcean

Page 15: Failure Of Cake PHP

第3の失敗第3の失敗関連するモデルの取得順を動的に指定する

2008/6/27 15BlueOcean

Page 16: Failure Of Cake PHP

第3の失敗 第3の失敗 – – 背景背景データは表示順の変更やフィルタリングすることを考えて、必要に応じて取得条件を設定する方針で開発を進めていた

2008/6/27 16BlueOcean

Page 17: Failure Of Cake PHP

第3の失敗 第3の失敗 – – 惨劇惨劇関連しているモデルの取得順を動的に変更できなかった◦User モデルが Review を hasMany している場合

◦×$this->User->Review->order = array();

◦×$order = array(“Review.id DESC”); $this->User->findAll($cond, null, $order);

2008/6/27 17BlueOcean

Page 18: Failure Of Cake PHP

第3の失敗 第3の失敗 – – 失敗の原因失敗の原因CakePHP の仕様を理解していなかった

bindModel() の用途が完全に見えていなかった

2008/6/27 18BlueOcean

Page 19: Failure Of Cake PHP

第3の失敗 第3の失敗 – – 解決策解決策bindModel() でアソシエーション設定を上書きすることで実現できた

bindModel() には「上書きする」という用途にも使える◦一度 find 系のメソッドを使えば元の設定に戻るため安心

2008/6/27 19BlueOcean

Page 20: Failure Of Cake PHP

第4の失敗第4の失敗

何も考えないで自作ビヘイビアの設定値をインスタンスへ保存する

2008/6/27 20BlueOcean

Page 21: Failure Of Cake PHP

第4の失敗 第4の失敗 – – 背景背景CakePHP 1.2 の登場からモデルの振る舞いを共通化しようというムーブメントが起こった( in 自分)

2008/6/27 21BlueOcean

Page 22: Failure Of Cake PHP

第4の失敗 第4の失敗 – – 惨劇惨劇同じビヘイビアをアタッチしているモデルで最後の設定しか反映されなくなった◦どうやらビヘイビアのインスタンスはアプリケーションでひとつらしい

2008/6/27 22BlueOcean

Page 23: Failure Of Cake PHP

第4の失敗 第4の失敗 – – 失敗の原因失敗の原因ビヘイビアはモデルインスタンスごとにインスタンス化されると誤解していた

2008/6/27 23BlueOcean

Page 24: Failure Of Cake PHP

第4の失敗 第4の失敗 – – 解決策解決策ビヘイビアの設定値をモデル名の要素の下に保存する

$this->__settings[$model->alias][ ~ ]

2008/6/27 24BlueOcean

Page 25: Failure Of Cake PHP

第5の失敗第5の失敗

コンポーネントのメンバ変数を startup() で初期化する

2008/6/27 25BlueOcean

Page 26: Failure Of Cake PHP

第5の失敗 第5の失敗 – – 背景背景共通性の高いロジックを外部において再利用する手段としてコンポーネントが用意されていた

これを利用しない手はないと思った

2008/6/27 26BlueOcean

Page 27: Failure Of Cake PHP

第5の失敗 第5の失敗 – – 惨劇惨劇startup() で初期化したはずのメンバ変数が未定義値に変わってしまった

原因究明に時間がかかった

2008/6/27 27BlueOcean

Page 28: Failure Of Cake PHP

第5の失敗 第5の失敗 – – 失敗の原因失敗の原因startup() の用途を間違えていたコンポーネントの設計意図を誤解していた◦C++ のトレイトや限定多重継承に近い使い方が正しいみたい

オブジェクト指向の理解が不足していた(教えて詳しい人)

2008/6/27 28BlueOcean

Page 29: Failure Of Cake PHP

第5の失敗 第5の失敗 – – 解決策解決策メンバ変数は startup() やコンストラクタ以外の場所で初期化する◦↑これらはクローンが実行するから

2008/6/27 29BlueOcean

Page 30: Failure Of Cake PHP

第6の失敗第6の失敗契約プログラミングを導入する

2008/6/27 30BlueOcean

Page 31: Failure Of Cake PHP

第6の失敗 第6の失敗 – – 背景背景テストよりも導入しやすく、確実に品質を向上させる仕組みが必要だった

2008/6/27 31BlueOcean

Page 32: Failure Of Cake PHP

第6の失敗 第6の失敗 – – 惨劇惨劇isset(), array_key_exists(),

is_array(), is_string() を多用する羽目になり、かえって可読性が低下した◦特に Amazon との連携

assert() の中に式を書いてしまったために、どんな条件に違反したのかわからなくなった

2008/6/27 32BlueOcean

Page 33: Failure Of Cake PHP

第6の失敗 第6の失敗 – – 失敗の原因失敗の原因assert() を書くコストを読み違えた

◦PHP のビルトインコンテナが配列しかないことが一因

◦PHP の配列は連想配列っぽい部分もあれば、そうでないっぽい部分がある

assert() 関数の中に式を書いてしまった◦正しくは恒等式を文字列で渡す

2008/6/27 33BlueOcean

Page 34: Failure Of Cake PHP

第6の失敗 第6の失敗 – – 解決策解決策テストを使うSet クラスを使うSet::check() で配列のパスを検証Set::extract() で深い配列から目的のデータリストを取得◦ほか CakePHP guide 内で紹介予定

2008/6/27 34BlueOcean

Page 35: Failure Of Cake PHP

第6の失敗 第6の失敗 – – 解決策 解決策 – – 効果効果ソースコードの行数が3割近く減った

2008/6/27 35BlueOcean

Page 36: Failure Of Cake PHP

第7の失敗第7の失敗車輪の再開発

2008/6/27 36BlueOcean

Page 37: Failure Of Cake PHP

第7の失敗 第7の失敗 – – 背景背景いわずもがな

2008/6/27 37BlueOcean

Page 38: Failure Of Cake PHP

第7の失敗 第7の失敗 – – 失敗の原因失敗の原因いわずもがなあえて言うなら想像力の欠如と調査不足

2008/6/27 38BlueOcean

Page 39: Failure Of Cake PHP

第7の失敗 第7の失敗 – – 惨劇惨劇弊社で再開発された主な車輪

◦レコードをスレッド形式で取得するメソッド

◦バリデーション機構◦国際化機構◦ログインチェックコンポーネント◦HABTM 取得形式→保存形式の自動変換

2008/6/27 39BlueOcean

Page 40: Failure Of Cake PHP

第7の失敗 第7の失敗 – – 解決策解決策Model::findAllThreaded() を使用する

CakePHP 1.2 の新しいバリデーションを使用する

i18n, l10n 関連クラスを使用するAuth コンポーネントを使用するSet::extract() を使用する

2008/6/27 40BlueOcean

Page 41: Failure Of Cake PHP

まとめまとめ

2008/6/27 41BlueOcean

Page 42: Failure Of Cake PHP

大切なこと大切なこと新しい機能を調べるときには想像力を働かせる

面倒がらずに開発コードも読むCakePHP を書いている人たちのことを想像する

近年の開発手法を勉強する(テストなど)

2008/6/27 42BlueOcean

Page 43: Failure Of Cake PHP

おしまいおしまいご清聴ありがとうございます

2008/6/27 43BlueOcean