ぼくのかんがえたさいきょうの
  うぇぶあぷりけーしょん
    ふれーむわーく


  cho45 <cho45@lowreal.net>
        株式会社はてな
自己紹介
id:cho45
http://www.lowreal.net/
株式会社はてな
 京都8F勤務
Perl (バックエンド)
JavaScript (フロントエンド)
Ruby (ツール作り)
Scala (たまにあそびで)
Java (Android アプリ)
Config::Pit
Config::ENV
Plack::App::CocProxy
SQL::NamedPlaceholder

JSDeferred
最近は
window.postMessage
   にハマっています
が
その話はしません
趣味
神社巡り
写真
プログラミング
コード群: http://github.com/cho45
日記: http://subtech.g.hatena.ne.jp/cho45/
本題
の前に
前提
1. 長期的にメンテナンスする
2. 大規模
3. 複数人開発
個人で使うフレームワークとか正
直どうでもいいと思う。
フレームワーク
つかってますか 
Catalyst,
 Jifty, Dancer, CGI::
 Application, HTTP::
   Engine, Mason,
Squatting, Continuity,
Maypole, Tatsumaki,
Mojolicious, Ark, Noe,
    Kamui, Amon2
                 ref. http://plackperl.org/
ぼくのかんがえたさい
きょうのうぇぶあぷり
けーしょんふれーむ
わーく
アジェンダ

● 良いフレームワークとはなにか
● 信頼性設計とかについて
● テストについて
ぼくのかんがえたさい
きょうのうぇぶあぷり
けーしょんふれーむ
わーく
を考える前に
フレームワークの
メリット   デメリット


  を整理します
メリット
共同開発しやすい
安全なフレームワークは安全
  形になるまで早い
  バッドノウハウの蓄積
  うまくいかないとき
フレームワークのせいにできる
共同開発しやすい
安全なフレームワークは安全

    特に重要
デメリット
読むコードが増える
  自由度がない
  拡張性がない

フレームワークが糞だと
 全てが糞になる
フレームワークを覚えるのに
  必死になりがち

  挙動が意味不明

 マジカルなことやりがち
良いフレームワークとは?
読むコードが最小
(共同開発のために)
 → 薄いフレームワーク

安全であること
 → 信頼性設計
読むコードが最小
だいたいフレームワークは
  結局ハマって
  全部コード読む
だいたいフレームワークは
  結局ハマって
  全部コード読む
 → 学習コスト増大
フレームワークのコードは
  マジカルすぎて
   意味不明
フレームワークのコードは
  マジカルすぎて
    意味不明
→ 読むと Perl に詳しく
フレームワークのコードは
  マジカルすぎて
    意味不明
→ 学習コスト アゲ♂アゲ
ある prepan.org 作者のつぶやき

「○○っていうフレームワークつかってるん
だけど、もう嫌なんだよね。
 フルスタックなんだけどドキュメントよくわ
からないし。
 中身読もうとすると意味不明だし」
薄いフレームワークが良い
      ↑
    良くいう
薄いフレームワーク
を極める
何も実装がない
フレームワーク
どういうこと?
限りなく薄いフレームワークとは
       ↓
     設計指針

      ● 安全
      ● 読むコード最小
フレームワークは
実装ではなく設計指針

共同開発に必要なのは
 共通の実装ではなく
  共通の設計指針
僕の考える設計指針=フレームワーク

   安全 (信頼性設計)
 読むコード最小 (メンテコスト)
信頼性設計
危険なことをするために
 より多くのコストが
 必要になるように
例: 最低限必要なXSS対策
デフォルトで HTML エスケープ

[% req.param('query') %]


危ないことをしようとするときは手間をかける

[% req.param('query') | raw %]
読むコード最小
3
       DRY

  3回コピペしたら抽象化しろ
(不必要な/下手クソな抽象化は悪)
設計例: Hatena Blog
長期的に開発することを念頭に

     柔軟性
新機能を加えるときに読むべき
   コードを最小化
    信頼性設計
柔軟性と
 読むべきコードの最小化を
  同時に達成しようとすると
ドメイン特化にならざるを得ない
安全で最小限な実装を
プロジェクト内に持つ

設計指針を明確にする
僕の考える設計指針=フレームワーク
                    再掲

   安全 (信頼性設計)
 読むコード最小 (メンテコスト)
設計指針

  安全 (信頼性設計)
読むコード最小 (メンテコスト)
  早い (ユーザ体験)
ディスパッチャ
Plack + Router::Simple + α

ビュー
Text::Xslate, JSON:XS, etc...

DBアクセス
DBI生 + SQL::NamedPlaceholder
(DBアクセスはコストがかかるので面倒にしとく)
既存実装(Ridge)を使わなかった理由
 → 安全じゃなかったら
 → テストも十分ではなかった

安全にする
テストを十分に

+ app.psgi から
あっちこっちいかずに読み下せるように
安全策
HTML出力時
自動エスケープ
 → XSS対策
POST時にトークン自動チェック
     → CSRF対策
JSON出力時
     XMLHtmlRequestの
X-Requested-Withを自動チェック
→ IE XSS 対策 / UTF-7攻撃対策 / JSON読み出し対策
自動で
X-Frame-Options: DENY
→ クリックジャッキング対策
iframeでロードされたフォームでは
 何か変更されないと submit 不可
   → クリックジャッキング対策
  (どうしても iframe 使う場合のフォールバック)
自動でできるだけ安全に
適切なデフォルトを設定
テスト
テストが大量にあってもメンテしない

レイヤー(Appとか)を増やすとテストが増える
       読むコードが増える

              ↓

       最小限の構成
      Model + Controller
Model のテスト
   (仕様があまり変わらない)
  ロジックのみ (DBアクセスなし)
    細かい挙動をチェック
カバレッジ重視 (ホワイトボックステスト)
例:

use Test::More;

# ロジックしかないので難しいところなし
my $e = Entry->new({body => '..'});
is_deeply $e->classes, [ ... ];
done_testing;
Controller のテスト
 (しばしば細かい仕様が変わる)
   ディスパッチ → 出力まで
Test::WWW::Mechanize::PSGI
  ユーザの挙動をシミュレート
     (ブラックボックステスト)
例:

use My::Test qw(create_hatena_user mechanize);

# DB アクセスとかはいい感じにしてる
my $user = create_hatena_user();
my $mech = mechanize($user);
my $blog_id = $mech->create_blog_ok;
ok $blog_id;
my $entry_id = $mech->post_entry_ok(blog_id => $blog_id);
ok $entry_id; done_testing;
早い
use DBI;
ORM は
勝手にDBひくな
ORM は
勝手にblessするな
コストがかかることを
便利にしてはいけない
実装
大枠としてはだいたいこんなかんじです
https://github.com/cho45/starter.pl/tree/master/templates/mywebapp

       (スケルトンジェネレータのテンプレートレベルのコード)
まとめ
ぼくのかんがえたさい
きょうのうぇぶあぷり
けーしょんふれーむ
わーく
とはなんだったのか
設計指針
サービス特化の
実装
僕の考えた最強の設計指針
僕の考えた最低限の設計指針

● 安全 (信頼性設計)
● 読むコード最小 (メンテコスト)
● 早い (ユーザ体験)

実装は必要に応じて選び
必要であれば最低限自分で書くのが良い
ご清聴ありがとうございました
  www.lowreal.net

ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011