N2 ToolBox(跡地)

跡地です。引っ越しました。http://d.hatena.ne.jp/nosen

フレームワークの生産性

2009-06-29 22:53:39 | 意見
たけぞうさんの日記より

フレームワークの選択は開発者の趣味?

これは釣られるエントリだなぁ。。

「フレームワークによる開発効率の差は開発者視点の趣味レベルの話でしかない」
「何を使っても開発コストは大差ない、それよりも安心して導入できることが大切だ」

と言われてしまったたけぞうさんの気持ちはすごくよく分かるのですが、
相手の方の意見は簡単に全否定することが難しい主張だと思います。

一般的に言って、あるプロジェクトが高い生産性を発揮したとして、
その生産性がプロジェクトを構成する特定の要素によって達成されたものかどうかを証明することは、
ほぼ不可能に近いと思います。

プロジェクトの生産性は、
「どういうフレームワークを使って開発するか」ということのほかに、
「どんな開発者が開発するか」
「どんな顧客のために開発するか」
「どんな作業環境で開発するか」
などなど、様々な要素に影響を受けるからです。

これら種々の要素のうち、特定のフレームワークが特に生産性の向上に寄与することを明らかにするためには、
フレームワークだけを他のものに交換し、
その他の条件はもとのままでプロジェクトを再実行する必要があります。

この「他の条件はもとのままで」ということは、実現不可能です。
同じ開発者が開発するとしても、その開発者には前にそのプロジェクトを実行した経験が
蓄積されてしまっているので、すでにその開発者の状態がすでにもとのままではない。
これは顧客についても同じことが言えます。
だからといって、開発者を他の人に入れ替えてしまったら、さらに条件が変わってしまいます。

加えて、特定の開発者が特定のフレームワークを使うから生産性が高くなる、等の
要素間の相互作用が生産性に影響を与える可能性まで考えると、

「あるフレームワークにはプロジェクトの生産性を高める効果がある」

ことを客観的に証明することはほぼ不可能であることが分かります。

それゆえ、

「フレームワークの生産性には、趣味レベルの違いしかない、どれ使っても一緒じゃん」

的な主張に対して効果的な反論をすることは難しいのです。

だからといって、冒頭の主張が正しいとは、僕は全く思いません。

同様の理由により、

「十分な安定性があれば、どんなフレームワークを採用しようと結果は変わらない」

こともまた証明することはできないからです。
というか、そもそも「十分な安定性」も同様に決して証明できないでしょう。

プロジェクトはその定義からして1回こっきりのもの、そして再現性の無いものに対して
科学的な手法で何かを証明することは出来ません。

陳腐なたとえですが、
それは1回こっきりの人生、いい大学に入って、大企業に就職したから幸せだなんて、
だれも言い切れないのと同じことです。

だから、フレームワークを選択するという問題は、むしろ宗教的な問題なのだと僕は思います。

大事なことは、開発者が自分が使うフレームワークの有用性を信じることができるかどうか。

少なくとも、いやいや押し付けられたフレームワークを使って開発者の生産性が向上することはありません。
それは、客観的に証明するというよりも、人間の共感する力によって理解すべきことです。

プロジェクトを成功に導くために、全力を尽くすのがプロだとすると、
たけぞうさんが遭遇した冒頭の意見は、その意見自体が正しいかどうかということよりも、
それを言ってしまうことによって、
「実績はそれほどでもないかもしれなけど、開発効率はいいはずだ」と
フレームワークの力を信じる開発者のモチベーションを意識せずに
殺してしまっているという意味で、空気の読めない素人くさい意見だと僕は思います。


Mercurial使用感

2009-06-06 00:51:36 | オープンソース
最近仕事ではPHPのフレームワークをつくったりして暮らしているのですが、
どうせなら使ったことないツールをためしてみようと思い、
バージョン管理にMercurial、Issue TrackingにRedmineを使っています。

もう使い始めて半年くらいになりますが、Mercurial は非常に良いですね。

バージョン管理のモデルがSVNよりずっと安全・確実で、おかしなことが起こりにくいのに、
運用はずっと柔軟にできます。

安全・確実さという点でいうと、リモートのリポジトリにローカルの変更点をPushする際に、
ローカルにないリモートのリビジョンと、ローカルのリビジョンをマージすることを
強制する点が良いです。

コミットだけしてアップデートをしなかったために起きる問題を回避できます。

マージする前に、ローカルのワーキングコピーの変更点をコミットすることを強制する点もすばらしい。
マージに失敗しても、ローカルの変更がどこかへ消えてなくなってしまう自体だけは避けることができます。

繰り返しマージする場合に、前回マージした場所を覚えていて、差分のみをマージする点もすばらしい。
既にマージしたところが差分として表示されないので、本当に重要な部分に集中することができます。

結果として、SVNで普通にUpdate/Commit する感覚でブランチがマージできるので、
恐ろしく気軽にブランチが切れます。

分散型であるが故の運用の柔軟性も魅力です。

リポジトリは思い立ったその場ですぐつくれるし、
リポジトリをHTTPで公開する設定も簡単です。
フレームワーク用のリポジトリをクローンして、フレームワークを利用するプロジェクトのリポジトリを
作り、適宜フレームワークへの変更点を個別プロジェクトのリポジトリにマージしながら開発するといったスタイルは
分散型のリポジトリであるが故に可能になることでしょう。

ローカルに完全なリポジトリがクローンされているが故に、対障害性も高いです。

ちなみにgitでなくMercurialを選んだのは、完全に勘です。
なんとなくマルチバイト文字の処理とか、Windows上での挙動とかが大丈夫そうな感じだったから。。くらいの感じ。

あと、オフラインで作業できるというのは、今日びそんなにメリットでないと思われるかも知れませんが、
使ってみると、つまらない会議に出席せざるを得ないときにこっそりコーディングできたりして意外に便利です。

Redmineの話はまたにします。

Programming in Scala

2009-06-03 07:37:32 | ブックレビュー
Programming in Scala: A Comprehensive Step-by-step Guide

以前からScalaには興味があったのですが、本格的にはまったのはこの本を読んでからです。
これは名著です。名著と言わざるをえない。
技術書もいろいろ読みましたが、徹夜で読みふけったのはこれが初めてです。
かなりぶ厚い本ですが、1ページめくるごとに新しい発見があって、まったく厚さを感じさせません。

文体は簡潔にして明晰であり、とても理解しやすいものです。

一見 複雑に見えるScalaの機能が、いかに一貫性のある、シンプルな思想に基づいて作られているのかがわかります。

これを読めば、きっとあなたもScalaが好きになる!

おすすめです。

ScalaからGAE/Jのデータストアを使う

2009-06-02 07:33:09 | その他
一旦途切れるとひどく長いこと中断してしまうのは、自分の悪い癖です。

別に忙しくもなかったし、書きたいこともあったのですが。。

というわけで、最近は Scala! Scala! と連呼している訳です。

一応 GAE/Jにも興味があるので、ScalaをGAE/J上で動かしてみているのですが、
ScalaのクラスをJDO経由で永続化できるようにするには、若干コツがいったので、それをメモします。

データクラスの定義は以下のようになりました。
package diet.entity
import javax.jdo.annotations.IdentityType
import javax.jdo.annotations.IdGeneratorStrategy
import javax.jdo.annotations.PersistenceCapable
import javax.jdo.annotations.PrimaryKey
import javax.jdo.annotations.Persistent

@PersistenceCapable {val identityType = IdentityType.APPLICATION}
class User(
  @Persistent
  var name: String
) {
  @PrimaryKey
  @Persistent {val valueStrategy = IdGeneratorStrategy.IDENTITY}
  var id: java.lang.Long = null
}



"id"をコンストラクタの引数にしていない理由は、プライマリキーの列に明示的に値を
指定したらAppEngineに怒られたからです。

でもこれだけだと、データクラスをEnhanceするときに、謎のjava.lang.VerifyErrorが発生します。

しらべたら、以下のようなバグがある模様。

http://www.datanucleus.org/servlet/jira/browse/NUCENHANCER-34

なので、GAE/J のSDKに同梱されているdatanuculeus のjarを最新版にいれかえたら、
何となく動いたっぽい。

ここまでやったところで、実はLow-Level APIをラップするクラスを書いた方がScalaっぽいのではないかと
思い始めた今日この頃です。