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

Post on 04-Jul-2015

44.543 views 5 download

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

ぼくのかんがえたさいきょうの

うぇぶあぷりけーしょん

ふれーむわーく

cho45 <cho45@lowreal.net>株式会社はてな

自己紹介

id:cho45http://www.lowreal.net/

株式会社はてな

京都8F勤務

Perl (バックエンド)

JavaScript (フロントエンド)

Ruby (ツール作り)

Scala (たまにあそびで)

Java (Android アプリ)

Config::PitConfig::ENVPlack::App::CocProxySQL::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 %]

読むコード最小

DRY3

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