Archive for 5月 2013
綺麗な設計を身に付けるためのSandi Metzルール
Webアプリやモバイルアプリの受託開発やコンサルティングを行うthoughtbot社のブログにて、Sandi MetzルールというRubyプログラマ向けのルールが紹介されていました。
このルールは、プログラマーでありPractical Object-Oriented Design in Rubyという書籍も執筆しているSandi MetzさんがRuby Roguesポッドキャストに出演した際に紹介していたものです。
そのルールは以下の通りです。
- クラス内のコードが100行を超えてはならない
- メソッド内のコードが5行を超えてはならない
- 4つより多い引数をメソッドに渡すようにしてはならない(ハッシュによるオプションもパラメーターとみなす)
- コントローラーではただ1つのオブジェクトだけをインスタンス変数化できる
- ビューは1つのインスタンス変数を参照し、そのオブジェクトに対するメッセージ送信のみを行うことができる(
@object.collaborator.value
は許可されない)
- ビューは1つのインスタンス変数を参照し、そのオブジェクトに対するメッセージ送信のみを行うことができる(
項目は少ないですが、方向性としてはThoughtworksアンソロジーという書籍で紹介されていた「オブジェクト指向エクササイズ」に通じるものがあります(あちらはJavaが主な対象でした)。
4つのルールとは別に、このルールを破ってもよい場合として、
- 適切な理由があると考えられる場合
- ペアプログラミングのパートナーやコードレビュアーが許可した場合
がルール0として挙げられています。
thoughtbotでは実際のプロジェクトにこのルールを適用してみたそうで、以下のような知見が得られたようです。
- ルール1 クラス内のコードが100行を超えてはならない
- Single Responsibility Principle(単一責任の原則)を徹底するようになる
- テストも100行以内に収めることを心がけたことで、1つのファイルで多くの機能をテストしすぎていたものを、よりフォーカスの定まった個別のテストに分割できた
- ルール2 メソッド内のコードが5行を超えてはならない
- メソッドを5行に収めるために、
「if〜else〜elsif〜end」のようにelseとelsifを合わせて使うことを避けるようになった(コメントで誤訳のご指摘をいただきましたので修正します。原文の意図は、if〜else〜endやif〜elsif〜endは使うけども、それらの組み合わせは5行を超えてしまうので使わない、ということのようです)else
やelsif
- 条件分岐で1行を使うのではなく、適切な名前のついたプライベートメソッドを作ってそれを呼ぶようになった
- コード片をプライベートメソッドとして抽出することで、命名が行われ、説明としても役立つようになった
- メソッドを5行に収めるために、
- ルール3 4つより多い引数をメソッドに渡すようにしてはならない(ハッシュによるオプションもパラメーターとみなす)
- Railsのビューヘルパーメソッドはとても多くの引数を要求するため、よい解決法が見つからない場合は、ルール0に立ち返り引数をそのままとした
ルール4については、実際のコードを例に詳しく説明がされています。
ルール4を適用すると、1つのコントローラーが1つのオブジェクトだけをビューに引き渡すように設計することになりますが、実際のプロジェクトでは必ずしも1つのコントローラーが1つのものを表示するとは限りません。
例えば、「トップページにアクティビティフィードと通知の数を表示する」といったようなケースも頻繁にありえます。thoughtbotではこのようなケースにFacadeパターンを適用し、アクティビティフィードと通知の数を内包したダッシュボードクラスを定義することで、コントローラーとビュー間のやり取りを単純化させることにしたようです。
詳細は、実際のコード例を見れば一目瞭然だと思いますので、ぜひ元のブログ記事も参照してみてください。
Git SubmoduleのトラブルをGit Subtreeで解決できると知っていますか?
ライブラリやフレームワークなど、外部のリポジトリで管理されているソースコードをプロジェクトに取り込む際によく使われているgit submodule
を使わないほうが良いという論争が起こっています。それを受けてgit subtree
を使うべきであるというエントリがAtlassianのNicola Paolucci氏がブログに投稿しています。彼はまずgit submoduleを使うべきではないという話題が盛り上がっているという事で3つの記事を参照したあとに、git subtreeを使うべき理由と使用例を挙げています。それによるとgit subtreeを使うべき理由は以下のとおり。
- ワークフローがシンプルなので管理が簡単。
- 古いバージョンのgitもサポートしている。(v1.5.2ですら。)
- サブプロジェクトのコードがcloneした直後に利用できる。
- subtreeはユーザに新しい学習を要求しない。subtreeを依存性の解決に使っていることは無視する事ができる。
- subtreeは新しいメタデータファイルを追加しない。例えばsubmodules が追加する.gitmoduleのようなファイル。
- モジュールの内容を別のリポジトリのコピーなどを他所に持たなくても編集できる。
もちろん、git subtreeを使う事への代償もありますが、これらは受け入れられるというあろうとして、下記のように挙げています。
- subtreeをマージする戦略について学ぶ必要がある。
- サブプロジェクトのアップストリームにコントリビュートするのはやや複雑になる。
- 親プロジェクトとサブプロジェクトのコミットを混ぜないようにする責任は自分自身にある。
具体的な利用例は元記事の残りを見て頂くとして、subtreeがsubmoduleを使う場合によくある問題をクリアしていることがわかります。基本的には新たなremoteを追加して別々にmergeしていくだけなのでブランチの管理のような感覚で利用できるという事でsubmoduleを避けてわざわざコピーしてしまったような場合はsubtreeの利用を検討してはどうでしょうか。
via:http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/
図解で見るスタートアップのはじめかた
タイトルどおりのインフォグラフィックが興味深いのでご覧ください。いちおう項目を書きだしておきます。
- 現在よりも未来を生きる
- 世界に足りないものを考える
- それやアイデアを書き起こす
- プロトタイプを作る
- プロトタイプを100人に見せる
- プロトタイプを納得行くまで改良する
- 共同創業者を探す
- 会社を登記し株式を分割する
- 資金調達を探しながらバージョン1を開発する
- ローンチし人々に何かをつくったことを知らせる
- ユーザにフォローアップを行い反応を見る
- 反応がなければ改良を行なってローンチする。(airbnbは3回ローンチしている)
- 反応があれば、ユーザを1000人獲得する
- 毎週、5%成長する(大変だけど、可能)
- 4年間、成長を維持する。レートを維持していれば2500万ユーザに到達している
- 大成功!
これなら誰でもスタートアップがはじめられますね!というわけには行かないですが、物事をシンプルに考えてみる助けにはなると思います。数字として出ている1000ユーザ、5%成長などが参考になるのではないでしょうか。
via:http://notes.fundersandfounders.com/post/50348129830/how-to-start-a-startup-15-steps
16の言語と57のフレームワークを比較したベンチマークが凄い
いつの時代もより高速に動作するフレームワークや言語に対する関心は高いものですが、そんな疑問に答えるWeb Framework Benchmarksの最新版が公開されています。こちらのベンチマークはテスト用のコードや環境がオープンソースになっており16の言語(C C# Clojure D Erlang Go Groovy Haskell Java JavaScript Lua Perl PHP Python Ruby Scala)と57のフレームワークについて最適な実装が集められてテストされているという点で一般性があります。また実行環境もEC2と実マシンの2種類をそれぞれ実行している点も興味深いです。
気になるテスト結果のうち特に複雑度の高いデータベースから複数件のデータを取得してHTMLページとして出力した場合の結果は下記のとおりです。
堂々のトップに輝いているのはServletで最大で1秒間あたり7,344レスポンスの凄まじい結果を叩きだしています。また2位に入っているgeminiはこのベンチマークを実行しているTechEmpower社の社内フレームワークとの事です。PHP(秒間あたり最大2,262レスポンス)やRails(秒間あたり最大461レスポンス)などスクリプト言語が下位に甘んじていますが、1台のEC2インスタンスが稼ぐ性能としてはそれでも充分なような気がします。1秒間に7,344レスポンスということは1日あたり6億以上のレスポンスをたった1台のサーバで返すわけです。逆に秒間100レスポンスであっても1日あたり864万レスポンスですよね。
その他テスト結果を見ていると気がついた点をいくつか挙げておきます。その他の結果も膨大ですので是非元の記事も併せてご覧になってください。
- gemini servlet go などは安定して上位入り
- Symfony Cake Fuel Sinatraなどが下位集団に居る事が多い(それでも秒間200〜1000レスポンスを処理しています)
- 只のphpは常にフレームワークよりも高速
RailsはSinatraよりも高速Railsの方がSinatraよりも高速な場合もある- Node.jsはServletに対して30%〜80%程度の性能
ベンチマークというと「〜〜はこんなに遅くない」的な意見が良く出がちですが、最下位であっても秒間数百レスポンスを処理しているので通常の利用では低速とは言えないでしょう。(もし気になる点があればGitHub上でテストコードにプルリクエストを送りましょう)
一方でフルスタック系のフレームワークや軽量フレームワークなどの速度が大きいケースや逆にrailsとsinatraの用に逆転しているケース、仮想環境と実マシンで結果に開きがあるケースなどがある点が興味深いのではないでしょうか。ご覧になった皆さんも気づいた点があれば是非ツイートやコメントでお寄せください。
via:http://www.techempower.com/benchmarks/#section=data-r4