2009/06/21

クラウドコンピューティングとKey-Valueストア

クラウドコンピューティングとKey-Valueストアは密接に関係している。
参考リンクをメモ。

【元ネタ】
Key Valueストアがリレーショナルデータベースを駆逐するシナリオの妥当性:Azureの鼓動:ITmedia オルタナティブ・ブログ

Bigtableの使い方教えます - ひがやすを blog

株式会社スターロジックの羽生章洋が書いてるブログ:端境期を感じるシステム開発 - livedoor Blog(ブログ)

株式会社スターロジックの羽生章洋が書いてるブログ:key-valueはデータディクショナリの夢を見るか - livedoor Blog(ブログ)

何故、Webシステム開発では、RDBだけでは物足りないのか?
Key-Valueストアは、どこに使われて威力を発揮するのか?
Key-Valueストアのアーキテクチャはどんなもので、どんな技術で実装されるべきなのか?
Key-Valueストアは、メインフレーム時代の技術の再来なのか?
Key-ValueストアはRDBを駆逐するのか?

| | コメント (0) | トラックバック (0)

2009/05/31

時代はO-Rマッピングからkey-valueストアへ

Apache CouchDBに関するメモ書き。
#理解が不完全なので、後で正しく書く。

【元ネタ】
Apache CouchDB: The CouchDB Project

Web 時代の非リレーショナルデータベース: 第 1 回 Apache CouchDB の概要とインストール

Web 時代の非リレーショナルデータベース: 第 2 回 Apache CouchDB と Ruby on Rails を使って wiki アプリケーションを作成する

Web 時代の非リレーショナルデータベース: 第 3 回 Apache CouchDB で MapReduce フレームワークに基づく問いあわせを行う

MOONGIFT: ? Web2.0時代のニュータイプDB「CouchDb」:オープンソースを毎日紹介

CouchDBはこのように説明されている。

CouchDB を探る


CouchDB はオープンソースのドキュメント指向データベース管理システムであり、アクセスには RESTful JSON (JavaScript Object Notation) API が使われます。
「Couch」という言葉は「Cluster Of Unreliable Commodity Hardware」の頭字語であり、CouchDB の目標を反映しています。
CouchDB の目標とは、極めてスケーラブルであると同時に、故障を起こしがちなハードウェア上で実行された場合でも高可用性と高信頼性を実現することです。
CouchDB は元々 C++ で作成されましたが、2008年4月、フォルト・トレランスを強化するために、このプロジェクトは Erlang OTP プラットフォームに移行されました。


CouchDBは関数型言語Erlangで作られた非RDBなDB。
RESTなWebAPIで問い合わせると、JSONが戻り値で返ってくる。
問い合わせ処理は MapReduce フレームワークに基づいて記述されているらしい。

使い道は、クライアントPCのユーザビリティ向上。
インターネットにつながっていないBTS、掲示板、Wikiでデータを更新して保存したい時に、クライアントのCouchDB に一旦保存して、そのデータは非同期にサーバーのRDBへ格納される。
この機能があれば、Webアプリは、画面ステータスをCouchDB に保存できるから、デスクトップアプリのように扱える。

多分、そういうイメージだと思う。

最近のWebアプリは、MVCモデルのうち、Viewの部分に技術革新が起きている。
最新バージョンのRailsが持つCookie Session Storeのように、非同期処理の機構をWebアプリに導入することで、Webアプリをデスクトップアプリのように、ネットワーク接続に無関係のまま扱えるようにしたい。

以前、友人から、最近の傾向としては、MVCモデルのうち、ViewでもAjaxやJasonのように、Viewの中にMVCモデルを作ろうとしているんですよね、と指摘してくれたことがあった。
多分、key-valueストアはその部分で使われるのだろう。

key-valueストアの良さは、関数型言語やMapReduceと相性がよいことだ。
CouchDB がErlangという風変わりな関数型言語で実装されているのは注目に値すると思う。
並列処理による処理の高速化(MapReduce)、分散システムによるフォールトレランス(耐障害性)などの特徴があるのだろう。

昨今のWebアプリの技術を鳥瞰してみると、RailsやSeasarでO-Rマッピングのインピーダンスマッチの問題は事実上解決されたと言える。

そして、技術革新の場所は、GoogleのMapReduce、Amazonのレコメンドエンジンなどの機能へ移っている。
これらはいわゆるデータマイニング。
膨大なトランザクションデータを大量のマシンパワーと関数型言語による並列処理で解析して、マーケティングや経営上の意思決定に生かす。

時代は、オブジェクト指向言語から関数型言語へ静かに移りつつあると思う。


| | コメント (0) | トラックバック (0)

2009/05/18

継続的インテグレーションをクラウド化する

Hudson作成者の川口さんのBlogを読みながら、継続的インテグレーションはクラウド化と相性が良いという指摘に関するメモ。

【元ネタ】
Hudson EC2 プラグイン - 川口耕介の日記

Hudson PXE plugin - 川口耕介の日記

Hudson Selenium PluginでHudsonクラスタをSelenium Gridに - 川口耕介の日記

HudsonクラスタをHadoopクラスタに - 川口耕介の日記

Hudson PXE plugin - かおるんダイアリー

【既存の問題】
XPを代表とするアジャイル開発におけるコード共同所有やテスト駆動開発などのプラクティスで、いわゆる下流工程の生産性を大幅Upできる。

しかしながら、自動テストや回帰テストを行う継続的インテグレーションは、システムが大規模化するにつれてビルド時間が膨大になるので、生産性が低くなっている。

そのため、「アート・オブ・アジャイル デベロップメント ―組織を成功に導くエクストリームプログラミング」においても、ビルドに含めるテストケースに優先順位をつけたり、夜間ビルドと即ビルドを切り替える等の方策を提示している。

でも、本来は単体テストだけでなく受入テストのテストケースも全て、JUnitで記述して、継続的インテグレーションによるビルド作業の一部としてしまいたい。
そうしなければ、テスト自動化の一番の利点である回帰テストの効果が生きてこない。

【一つの解決策】
一つの解決策は、テスト環境を仮想化し、継続的インテグレーションをクラウド化することだ。

例えば、OSやJDKなどのバージョンが異なるサーバー環境はVMWareで仮想化して、複数の環境を用意できるようにする。
更に、クライアントのOSやブラウザの異なるクライアント環境も仮想化しておく。
そして、Hudsonによる自動ビルドは、複数のビルドサーバー上で並列処理できるようにする。

この利点は、格安のハードウェアを並列に処理させることで、マシンパワーで持って大量のJUnitをこなすのができること。
ビルド作業の並列処理だから、見かけ上の時間は大幅に短縮されるはず。

想像であるが、一つの業務系Webシステムをリリースできる品質に持っていくために、単体~受入テストの全てのテストケースを数えたら、おそらく最低1万件近くは必要だろうと思う。
それだけの桁のテストケースを回帰テストも含めてデイリービルドするには、仮想化+クラウド化は必須の技術だ。

【可能性】
最近のHudsonの動向を見ると、もはやCIツールではなく、汎用クラウド化ツールと呼んだ方がいいかもしれない。

例えば、
Hudson Hadoop pluginでクラスタ処理する。
Hudson PXE pluginでネットワーク接続した複数のOSを制御する。
Hudson EC2 pluginでAmazonEC2のクラウド環境を使う。
Hudson Selenium PluginでHudsonクラスタをSelenium Gridにする。

いずれも、格安のサーバー、仮想化されたビルド環境をバッチ処理のために使うという発想。

しかし、これだけクラウド化の利点があるにも関わらず普及していないのは、クラウド化する設定作業が大変だからだ。

でも、Hudsonはクラウド化の設定作業を楽にする方向で進化しているようだ。
Hudsonを十分に使いこなせれば、Hudsonによってビルド管理やリリース管理を大幅に効率化できるだろう。

XPが出現して10年近く経ってようやく、プロジェクト管理や構成管理、リリース管理などがIT化できる状況が整ってきた。
この技術革新の流れを追いかけていきたい。


| | コメント (0) | トラックバック (0)

2009/05/06

Antリファクタリングカタログ

ThoughtWorksアンソロジー ―アジャイルとオブジェクト指向によるソフトウェアイノベーション」本を読んで興味深くかつすぐに使えそうな箇所は「Antビルドファイルのリファクタリング」だった。
以下メモ書き。

【1】「ThoughtWorksアンソロジー ―アジャイルとオブジェクト指向によるソフトウェアイノベーション」の1章に「ビジネスソフトウェアの「ラストマイル」を解決する」という章がある。
長年、継続的に機能追加されて肥大化したシステムへいかにアジャイルにリリースできるか?という「ラストマイル」問題を提示している。

XPが提示したプラクティス「継続的インテグレーション」「テスト駆動開発」は、高速・高品質な開発を可能にした。
しかし、本番環境へのデプロイ+リリースのプロセスではその恩恵がない、と。
理由は、3つある。
一つ目は本番環境は大変高価であり、二つ目は検証が複雑で、三つ目は検証の工数が大きすぎるからだ、と。

アジャイル開発の最終目標は「バージョンのないソフトウェア」を提供することにある、と。
つまり、仕様変更の要求が発生したら、それを開発して完成したら、すぐにリリースして本番稼動できることだ、と。

この指摘は、アジャイル開発の別の問題点を示していると思う。
今僕が考えているチケット駆動開発、プロジェクト管理サーバーは、アジャイル開発のプロジェクト管理へ適用して、大幅に改善できると考えている。
上記では、大規模システムへアジャイル開発を適用した場合、開発プロセスの効率化ができたのを前提とした上で、リリース管理に問題があることを指摘している。

ThoughtWorksアンソロジー ―アジャイルとオブジェクト指向によるソフトウェアイノベーション」にも書いているが、上記にあげたリリース管理の問題点は、二つの技術で大幅に改善できると思う。
一つは、ビルド作業やリリース作業の並行化。
いわゆる並行ビルド、並行リリース。
Hudsonなら、並行ビルドも簡単に操作可能。
これによって、二つ目と三つ目の問題が解決できる。

もう一つは、本番環境を仮想化して複数のテスト環境を作って、検証可能にしておくこと。
昨今ならVMWareで仮想イメージを簡単に作ることができる。
これによって、一つ目の問題も解決できる。

実際の現場ではまだ一つのアイデアに過ぎないだろうが、そのアイデアを実現する技術は既に登場していることに注意しよう。

【2】「ThoughtWorksアンソロジー ―アジャイルとオブジェクト指向によるソフトウェアイノベーション」の10章にAntビルドファイルのリファクタリングが書かれている。
Antビルドファイルのリファクタリングは実施した経験が無かったけれど、さっそく使ってみたい技術の一つ。
Antだけでなく、MavenやRakeなどでもその発想は使えるはずだ。

【元ネタ】
2009-01-05 - yyamanoの日記

【Antリファクタリングカタログ】

【1】ターゲットの抽出
* macrodefの抽出 - コードブロックをmacrodefとして抽出する
* ターゲットの抽出 - 大きなターゲットを小さなターゲットに分割し、依存関係を定義する
* ターゲットのラッパービルドファイルへの移動 - CI用のターゲットは別ビルドファイルに移動する
* デプロイ用コードのimport先への分離 - デプロイ用のコードは別ビルドファイルに移動する
* build.xml内へのラッパースクリプトの取り込み - シェルスクリプトで定義しているパスやオプションをビルドファイルに移動する
* 明確なターゲット名の導入 - ターゲットとプロパティで異なる命名規則を使う
* ターゲット名の名詞への変更 - ターゲット名にはプロセスではなく成果物の名前を使う

【2】コメント取り込み
* descriptionによるコメントの置き換え - XMLコメントのかわりにdescription属性を使う
* taskname属性の追加 - タスクの意図を明確にし、実行状況を簡単に把握できるようにtaskname属性を使う

【3】実行処理
* 内部ターゲットの強制 - 内部ターゲットの先頭にハイフンを追加し、コマンドラインから呼べないようにする
* 出力ディレクトリの親ディレクトリへの移動 - 生成される成果物の出力先を一カ所にまとめる
* applyによるexecの置き換え - execのかわりにapplyを使う
* CI Publisherの利用 - タグ処理は独立したターゲットとして分離する

【4】プロパティや依存関係の共通化
* 宣言の導入 - if条件分岐のかわりに、プロパティとimportを使う。
* 依存によるcallの置き換え - 明示的なantcallのかわりに宣言的な依存関係を使う
* プロパティによるリテラルの置き換え - 頻繁に使うリテラル文字列をプロパティに置き換える
* filtersfileの導入 - filter要素のかわりにプロパティファイルとfiltersfile属性を使う
* プロパティファイルの導入 - プロパティ定義を外部ファイルに移動する
* 要素のantlibへの移動 - 複数のプロジェクトで使われるコードをantlib.xmlに移動し配布する
* filesetによる多数のライブラリ定義の置き換え - pathelement要素のかわりにfileset要素を使う
* 実行時プロパティの移動 - ビルドに使うプロパティと実行時に使うプロパティを分離する
* IDを用いた要素の再利用 - 重複したpathのような要素をidを使い共通化する
* プロパティのターゲット外部への移動 - ターゲット内部で定義されているプロパティをターゲットの外に移動する
* locationによるvalue属性の置き換え - パスを表現するプロパティではvalue属性のかわりにlocation属性を使う


上記のリファクタリングカタログで面白いと思ったのは、コメントをタスクの属性(description, taskname)にしてしまうこと。
もう一つは、ターゲットを処理ではなく成果物の名前にすること。

Antは宣言的であってスクリプト言語ではない特徴がある。
だからこそ、ターゲットは成果物の名前にして、コメントも宣言に取り込んでしまうようだ。

このAntリファクタリングカタログは、ファウラーのリファクタリング本(リファクタリング―プログラムの体質改善テクニック)のように、抽出とインライン化の組み合わせなどもあり、非常に有用だと思う。


| | コメント (0) | トラックバック (0)

2009/04/26

Javaから関数型言語へ

ジョエルのWikiはいつ読んでも面白い。
JavaよりもScheme、Haskellなどの関数型言語の習得が何故必要なのか、を説明している。

【元ネタ1】
Javaスクールの危険 - The Joel on Software Translation Project


(前略)
関数プログラミングを理解していなければ、GoogleをあれほどスケーラブルにしているアルゴリズムであるMapReduceは発明できない。
MapとReduceという用語はLispと関数プログラミングから来ている。
純関数プログラムは副作用がなく容易に並列化できるということを6.001に相当するプログラミングの授業で聞いて覚えている人には、MapReduceは容易に理解できる。
GoogleがMapReduceを発明し、Microsoftが発明しなかったという事実は、Microsoftが基本的な検索機能についてキャッチアップの途上にあり、一方Googleは次なる課題へと進んでいることを示している。
世界最大の並列スーパーコンピュータを構築しているのだ。
この流れの中でいかに遅れを取っているかをMicrosoftがちゃんと理解しているとは思わない。
(後略)


最近のプログラミング技術の傾向として、関数型言語の発想が必要になる場面が増えたように思う。
例えば、Googleの検索エンジンの背後にあるアルゴリズムMapReduceだけではない。
Amazonのレコメンドエンジンの背後にあるアルゴリズム協調フィルタリングも、同様だ。

WebもマルチコアCPUも、並列処理、分散処理のアイデアを使えば劇的に変わる可能性がある。


ジョエルのWikiには、関数型言語で再帰を使う問題が載っている。

【元ネタ2】
試してみよう - The Joel on Software Translation Project


1a. (MIT-Scheme) 次の関数

(define (accumulate combiner null-value l)
(if (null? l)
null-value
(combiner (car l)
(accumulate combiner
null-value
(cdr l)))))

を用い、リストの平方和を計算するsum-of-squaresを実装せよ。

例:(sum-of-squares '(1 2 3 4 5))

1b. (JavaScript) Schemeなんか知らないかもしれないね。次の問題は1aをJavaScriptにしたものだ。

次の関数

function accumulate(combiner, nullValue, l)
{
if (l.length == 0)
return nullValue;
var first = l.shift();
return combiner(first, accumulate(combiner, nullValue, l));
}

を用い、リストの平方和を求めるsumOfSquaresを実装せよ。

例:sumOfSquares([1,2,3,4,5])


Schemeは取っ付きにくいけれど、JavaScriptなら別だ。

関数脳のつくり方のように、リストを元ネタとして、リストに関数を適用する発想が必要だ。



| | コメント (0) | トラックバック (0)

2009/04/04

Codestrikerのインストール方法

Perl製コードレビューWebシステムCodestrikerをインストールできたのでメモ。
但し、ReviewBoardに比べると、インストールははるかに難しかった。。

【元ネタ】
Perl製のソースコードレビューソフトウェア「Codestriker」

Codestriker: Homepage

Codestriker:Metrics Report

ソースコードレビューツール「Codestriker」

CodeStrikerとSubversionの連携設定

CodeStrikerでコードレビューをする


CodeStrikerでコードレビューをする~その2

【必須環境】
以下、CentOS上で下記ツールはインストール済みとする。

Perl
Apache

下記のCPANライブラリ:

LWP::UserAgent(any)
CGI(v2.56)
Net::SMTP(any)
MIME::QuotedPrint(v2.14)
DBI(v1.13)
Template(v2.07)
HTML::Entities(any)
File::Temp(any)
XML::RSS(v1.05)
Encode::Byte(any)
Encode::Unicode(any)
DBD::mysql(any)
Authen::SASL(any)

上記のCPANを全てインストールするのがかなり面倒。。
ソースからインストールするよりも、yumやapt-getで入れた方が早いだろう。

【1】インストール方法
1.ソースを持ってくる。

tar zxvf codestriker-1.9.7.tar.gz
mv codestriker-1.9.7 codestriker
ln -s codestriker /var/www/cgi-bin/codestriker

2.MySQLへDB作成

mysql -u root
CREATE DATABASE codestrikerdb CHARACTER SET utf8;

GRANT SELECT,INSERT,UPDATE,DELETE,INDEX,ALTER,CREATE,DROP,
REFERENCES ON codestrikerdb.* TO codestriker@localhost
IDENTIFIED BY 'codestriker';

FLUSH PRIVILEGES;

3.CodeStrikerの設定ファイル「codestriker.conf」を編集する。

14行目:
$db = 'DBI:mysql:dbname=codestrikerdb;host=localhost;
mysql_socket=/var/lib/mysql.sock';

28行目:
# Database user.
$dbuser = 'codestriker';

# Database password.
$dbpasswd = 'codestriker';

$admin_users = [ '管理者のメールアドレス' ];
・・・・・

104行目あたりから、連携するバージョン管理システムを設定する。

4.インストール実行。
Railsのように、MySQLへテーブルが作られる。

./bin/install.pl

足りないCPANライブラリはメッセージ表示される。

5.Apacheのhttpd.confへ下記を追加する。
CodestrikerはPerlなので、CGIの設定方法と同じ。


ScriptAlias /codestriker/ /var/www/cgi-bin/codestriker/cgi-bin/
Alias /codestriker/html/ /var/www/cgi-bin/codestriker/html/

<Directory "/var/www/cgi-bin/codestriker/cgi-bin/">
AllowOverride None
Options ExecCGI
Order allow,deny
Allow from all
SetHandler cgi-script
</Directory>

<Directory "/var/www/cgi-bin/codestriker/html/">
AllowOverride None
Allow from all
</Directory>

Apacheを再起動後、
http://IPアドレス/codestriker/codestriker.pl
で表示可能!


【2】Webシステムとしての使い勝手、色合いなどのUIは、ReviewBoardの方がいいと思う。
しかしながら、Codestrikerには下記のようなレビュー記録のメトリクスを出力する機能がある。

Codestriker:Metrics Report

上記は、実施日ごとに、レビューのステータス(完了、解決、無効)とレビューコメント数を集計する。
この集計から、レビューの活発具合、レビューの貢献具合を見ることができる。


コードレビューWebシステムをレビュー工程の一プロセスへ含むように運用するには、いくつかのハードルを越える必要がある。
だが、レビューをもっとお手軽に行えて、更にはDBにあるレビュー記録からメトリクスを出力して、品質を測定できる可能性がある。

色々試してみたい。

| | コメント (0) | トラックバック (0)

ReviewBoardのインストール方法

Python製コードレビューWebシステムReviewBoardをインストールできたので、その設定方法をメモ。

【元ネタ】
Documentation - reviewboard - Documentation for Review Board - Google Code

Review Board | Take the pain out of reviewing code

ReviewBoardのインストール | Ryuzee.com

monospace blog ? オンラインソースコードレビューツールのReviewBoardをインストールしてみた

monospace blog ? ソースコードレビューツールReviewBoardの使い方メモ 前編

monospace blog ? ソースコードレビューツールReviewBoardの使い方メモ 後編

monospace blog ≫ ReviewBoardを使ったコードレビューのワークフロー

【必須の環境】
以下、CentOSで下記ツールはインストール済みとする。

Python version 2.4 or higher
Django version 0.97 or higher
PIL - The Python Imaging Library
patchutils
MySQL 5.0.31 or higher
MySQL-python
Subversion
pysvn

【1】インストール方法

1.MySQLでReviewBoard用データベース作っとく。

mysql -u root
create database reviewboard character set utf8;

ついでに、ReviewBoard用ユーザも作る。

grant create, select, insert, update, delete, alter, lock tables on reviewboard.* to 'reviewboard'@'localhost' identified by 'reviewboard';
flush privileges;

2.ReviewBoardのソースを持ってくる。

svn checkout http://reviewboard.googlecode.com/svn/trunk/reviewboard reviewboard
chmod -R 777 reviewboard

次に初回アクセスだからディレクトリを作る。

cd reviewboard
mkdir htdocs/media/images
chmod -R 777 htdocs/media

3.設定ファイルへMySQL設定を追記する。

cp -ip settings_local.py.tmpl settings_local.py

DATABASE_ENGINE = 'mysql' # 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
DATABASE_NAME = 'reviewboard' # Or path to database file if using sqlite3.
DATABASE_USER = 'reviewboard' # Not used with sqlite3.
DATABASE_PASSWORD = 'reviewboard' # Not used with sqlite3.
DATABASE_HOST = '' # Set to empty string for localhost.
DATABASE_PORT = '' # Set to empty string for default.

SECRET_KEYの生成は1行で書けます。

python -c "import random;CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789%^&*(-_=+)';print ''.join([random.choice(CHARS) for x in range(50)])"

これをSECRET_KEYの値として設定する。

# Make this unique, and don't share it with anybody.
SECRET_KEY = 'p8923yaernva4tqkwdavo8qi2v7349qc3q23479-p123youwidhoq8923yco'

ついでに、時間と言語も設定する。

TIME_ZONE = 'Asia/Tokyo'
LANGUAGE_CODE = 'ja'

4.初期化テーブルの作成で下記コマンドを実行。
RailsみたいにMySQLにテーブルが作られます。

python manage.py syncdb

djangoサーバをノーハングアップで稼動させる。

nohup python manage.py runserver IPアドレス:8000 &

http://IPアドレス:8000/dashboard/
で起動する

これでようやく画面が出る。
ID・PW:reviewboardでログインできる。


但し、ログを見ると、下記ライブラリも必要みたい。

Pygments
 ハイライト表示機能
Installing PyLucene
 全文検索機能
memcached
 メモリキャッシュ

【2】他Blogを見ながら、管理画面で色々設定する。
下記に色々説明がある。

Review Board | Media and Links

Review Board - a set on Flickr

ReviewBoardで興味を惹いたのは、バグ管理システムと連携できる点だ。
コードレビューのコメントを書く時、バグ管理IDを入れると、該当チケットにリンクする。
この機能のおかげで、コードレビューで修正やリファクタリングが発生したら、チケットで作業状態を追跡できる。

つまり、チケットの発生源はReviewBoard、実際のタスク管理はRedmineで行う運用になる。
おそらく下記の記事のような運用フローになるだろう。

monospace blog ≫ ReviewBoardを使ったコードレビューのワークフロー

TestLinkでも似たような運用になる。
つまり、バグの発生源は普通、テストケースをテストして判明するから、TestLinkの失敗したテストケースにバグ管理IDを紐づける機能がある。
このおかげで、テスト工程やバグ発生源はTestLink、実際のバグ修正の管理はRedmineのように運用できる。

従って、変更管理プロセスはRedmineでやるが、変更要求はTestLinkやReviewBoardから発生するという流れになる。

最近強烈に感じるのは、ツールの運用で開発プロセスが大きく改善されることだ。
コードレビューはペアプロの代替手段という効用もあるから、色々試してみようと思う。


| | コメント (0) | トラックバック (0)

コードレビューWebシステムが必要な理由

最近、コードレビューWebシステムに興味を持っている。
アイデアをメモ。

【元ネタ】
プログラマの思索: ソースインスペクションを真面目にやるGoogle、MS

プログラマの思索: コードレビューはペアプログラミングの代替手段

プログラマの思索: レビューはペア作業であるべき


最近思うのは、SW開発でレビュー工程が最大のボトルネックになっていること。

レビューは、設計書を作成完了した後、設計書に従って実装完了した後に行われる。
レビューの目的は二つあると思う。
一つは品質チェック。
他方は、チーム全体で仕様や設計思想を情報共有すること。

しかし、レビューがうまく機能していない。
実際は、レビューが品質強化につながっておらず、むしろ、要件定義の代替プロセスになっていたり、ソースチェックで自動化できるぐらいのレベルでしか、情報共有できてない。

僕の考えでは、XPのペアプロのように、レビューは二人のペアで、レビューイーのPCの前でレビュー結果を即反映していく方がはるかに生産性が高いと思う。
理由は、レビュー結果は紙ベースで残すため、伝言ゲームになりがちで、せっかくの仕様が漏れやすいから。
また、レビュー指摘事項を記録に残して、レビュー結果をいつ反映したか、というレビュー作業ステータスを管理するのは、又もやExcelのため、ステータスの追跡やステータス集計がやりにくい。

そこで、コードレビューWebシステムを導入してみることを考えている。
特にコードレビューは、場所や時間が離れた場でもレビューできる状況がBetterだと思う。

Perl製のソースコードレビューソフトウェア「Codestriker」

VMWareの開発でも利用されているソースコードレビュー共有ソフトウェア「Review Board」

上記は、コードレビューをWebシステム上で行うもので、僕としては画期的だと考える。
理由は、場所や時間が離れていても、誰でも簡単にレビューをコメント(チケット)として書いて残せること、更には、レビュー結果がDBにあるため、色んなメトリクスを出力できるから。

ReviewBoardには、二つのソースのDiff画面で、任意の場所にコメント(チケット)を付加できて、そのチケットのステータスを追跡できる仕組みがある。
この仕組みは、チケット駆動開発によるタスク管理と同じ発想。
つまり、レビュー指摘のチケットのステータス(未着手・レビュー修正中・レビュー反映完了)を追跡できるため、レビューのワークフロー管理を行うことができる。

Codestrikerには、レビュー指摘件数とレビュー作業のステータス(未着手・レビュー修正中・レビュー反映完了)を実施日でクロス集計して表示する機能がある。
この仕組みは、レビュー実績の信頼度成長曲線のようなもの。
つまり、ある程度のボリュームでレビューの指摘が上がり、それに対応していくと、ある時点でレビュー指摘件数が減り、最終的には品質が歩溜まりに達するだろうと考えられる。

だが、上記のコードレビューWebシステムが良いと思うのは、誰もが気軽にレビューコメントをチケット登録できることだ。
普通、レビューワーは業務知識を知り尽くしている人、プログラミング技術に長けている人がその役割を担うが、チームに新規加入した人や新人も気軽に質問できるような雰囲気が出てくる。

例えば、Googleにおけるコードレビュープロセスの概念では、信頼関係の強化が含まれている。
つまり、レビューワーとレビューイーがレビュー工程を通して、お互いの信頼関係を高めながら、仕様や技術を共有していくことが含まれている。
レビューは単なる欠陥のあら探しではないのだ。
レビューを通じて、チーム全体で設計思想を共有することで、どのメンバーでもシステムの運用保守をできるような環境を作る。
このような環境作りがあれば、特に、新人や新規加入メンバーのスキルアップに非常に役立つ。

しかしながら、コードレビューWebシステムを稼動できたものの、実際の運用はハードルが高かった。
特にコードレビューしていくと、リファクタリングに関係するチケットが増えてゆき、それらは内部課題やリスク管理のようなイテレーションに含まれてしまい、一般に優先度が低くなる。
だから、即修正する場合があまり増えない時がある。
理由は、まずチームにレビューというプロセスが無かったり、コードレビューの作業と、Redmineチケットの関係付けが曖昧だったから。

でも最終的には、レビューはペアプロとして実装され、そのレビュープロセスは、チケット駆動開発の一プロセスとして組み込まれるべきだと思っている。


| | コメント (0) | トラックバック (0)

2009/04/03

AmazonがMapReduceを公開

AmazonがMapReduceのAPIを公開していたのでリンクしておく。

Amazon Elastic MapReduce

昨年のkansai.pmで、はてなの伊藤さんがMapReduceの講演をした時の感想もメモ。

プログラマの思索: MapReduceメモ

プログラマの思索: 【感想】Kansai.pm第9回ミーティング

| | コメント (0) | トラックバック (0)

2009/03/04

関数脳のつくり方

関数型言語の特徴について、牛尾さんが良い記事を書かれていたのでメモ。

第7回 関数脳のつくり方 First Season:ITpro

 関数型の言語では,リストがとても強力なので,ループをまわしてと考えるのではなく,まず元になるリストを作るという発想をして,そこに「関数」を適用するというイメージを持つことを繰り返し強調しておきます。
 そういうスタイルでコーディングするので,ループカウンタや,一時変数のように途中の値を保持するようなコーディングは基本的に行いません。

元となるリストを作り、それに関数を適用するやり方は、まさにブロックそのもの。
イテレータと同じ。

| | コメント (0) | トラックバック (0)

2008/12/27

商用開発は保守性よりも信頼性を重視する

保守性と信頼性のトレードオフについて良い記事があったのでメモ。

【元ネタ】
森崎修司の「どうやってはかるの?」 > 保守性と信頼性のトレードオフ : ITmedia オルタナティブ・ブログ

記事で面白いと思ったのは下記2つ。
一つは、オープンソースは保守性が重視されること。
ソースが読めないシステムは、最終的には誰も使わなくなるから。
その意味では、オープンソースはプログラミングのレベルが高いシステムと言える。

もう一つは、商用開発は信頼性の方が重視されること。
本番稼動しているシステムは、止まってはいけない。
保守性を実現するためにリファクタリングして、障害が発生したら、元も子もない。
だから、リファクタリングできずに、重複したロジックがあちこちにできたりして複雑になってしまって、最終的には誰もソースを改変できなくなる可能性がある。
商用システムは、最終的にはパッチで継ぎ接ぎだらけの汚いソースが増えているだろう。

実際のSW開発では、保守性と信頼性は両方とも大事。
でも、トレードオフの関係になる場合もありうることを知っておくべきだろう。

| | コメント (1) | トラックバック (0)

2008/10/27

コードレビューはペアプログラミングの代替手段

garyoさんに教えてもらった「Google 工藤拓さん講演「大規模ソフトウェア開発を支えるGoogleのテクノロジー」」の感想を書く。

【1】コードレビューができないプロジェクトの問題点

コードレビュー以前に、レビューというプロセスが存在しないプロジェクトは数多い。
相次ぐバグ修正や仕様変更にひっきりなしに対応するのに追われて、設計書やコードを書いただけになってしまいがち。
特にデスマーチプロジェクトでは、雑な作業の結果である雑な成果物ばかり作られる。
読んでも誰も分からない、とか、誤植が多い、などの症状が頻発するだろう。

レビューのない開発チームでは、設計思想や運用ルールの情報共有ができていない。
どんな開発でも、フレームワークやハードを含めたアーキテクチャの上で設計してプログラミングする。
その思想を理解するには、最初は時間がかかる。
特に昨今のWebシステム開発では、3カ月おきに開発者が入れ替わりがちだから、途中加入の開発者は設計思想や運用ルールに慣れるまで生産性が落ちる。

また、プログラミングには誰でも癖がある。
色んな人に見られた方がプログラムの可読性は必ず上がる。

だからこそ、レビューを上手に使って、チームに早くスムーズに溶け込めるように使いたい。

【2】コードレビューはペアプログラミングの代替手段

Googleはコードレビューに力を入れている。
上記Blogの下記のフレーズが気に入った。

(コードレビューは)ペアプログラミングの良い代替手段
(コードレビューは)開発者間の信頼関係を築く
 システムの引き継ぎが容易
 次のプロジェクトに行きやすくなり、流動性が高まる

XPのプラクティスの一つであるペアプロには、賛成も批判も多い。
しかし、ペアプロの目的や利点をはっきりさせれば、導入したくなるはずだ。

実際の開発や運用では、ペアで作業する場面は多い。
本番リリース作業や本番のデータ保守作業は、普通は2人でペアで行うのが普通だろう。
本番作業では1度のミスも許されないから、それだけのコストをかける価値がある。

また、新しい技術を取り入れて技術検証する時などは、席は離れていても、実質2人で議論しながら試行錯誤する時が多いだろう。
普通は一人で考えても上手くいかないから。

コードレビューの目的や利点は、上記Blogから考えると下記2点に尽きると思う。

1.ペアプロの代替手段
2.プロジェクトの引継ぎが楽になる

コードレビューとはペアプロであり、それによって情報が共有され、信頼関係が作られるからこそ、作業の引継ぎがスムーズになる。
コードレビューはあら探しではないのだ。

XPのペアプロは必ず同席という物理的制約があるが、ReviewBoardCodestrikerなどのコードレビューWebシステムを上手に運用すれば、チャットのような感覚でコードレビューできる。

更にコードレビューしたコメントをチケットのように、重要度や優先度、作業状態を付けて管理できれば、ソースの品質は更に高まるだろう。


| | コメント (0) | トラックバック (0)

2008/09/14

Redmineインストールメモ

Redmineのインストールや設定に関するメモ。

【1】Passengerをインストールすると、RailsをApache単独で稼動できる。

http://redmine.jp/tech_note/apache-passenger/

gem install passenger
passenger-install-apache2-module

後は、httpd.confの設定だけすればいい。

Passengerの利点は、RailsがPerlやPHPと同じ感覚で運用できることだ。
今後のビジネスを考えると、RailsをJRubyで動かすか、Apacheで動かすか、どちらかが重要になるだろう。
要注目の技術だと思う。

【2】Wikiを使うには、下記を実行。

gem install RedCloth

 但し、活動欄に表示されるチケット内容は、Wikiのシンタックスがそのまま表示されてしまう。

【3】日本語文字化け対応

http://chocoapricot.cocolog-nifty.com/blog/2008/06/redmine_445a.html

この対応で、エクスポートしたCSVの文字化けが直った。

【4】マイカレンダーの表示を1週間→2週間に変更するパッチ

http://d.hatena.ne.jp/ywatase/20080506#p1

 ログイン直後の画面のカレンダーが2週間に広がる。

【5】Redmineで統計を表示する

http://chocoapricot.cocolog-nifty.com/blog/2008/06/redmine_75d8.html

(1) SVGを表示させるプラグインを入れる。

(2) SVGの日本語が文字化けしていたら、redmine/lib/SVG/Graph/Graph.rbを下記のように修正する。

・「font-weight: bold;」→「font-weight: normal;」
・「font-family: "Verdana", sans-serif; 」→「font-family: HGGothicM , Verdana, sans-serif; 」

 統計は、月別・開発者別のSVNリビジョン回数、SVNコミットファイル数を出力してくれる。
 statSVNの方がたくさん機能があるが、これだけでも、開発者の負荷が良く分かる。
 能力の高いプログラマは、3ヶ月という長期スパンでは、コミット回数もLOCも一番多くなる。

 開発者によると、個人成績みたいなものなのでプレッシャーがかかるらしいけれど。

【6】RedmineをJRubyで動かす

http://gihyo.jp/dev/serial/01/redmine-use/0007

 ただ今実験中。
 この運用が検証できたら、RailsをJavaで動かすのは問題なくなる。

【7】チケットとSVNコミットを関連付ける方法は2種類ある。

http://www.redmine.org/wiki/1/RedmineSettings

Redmineの設定欄にある「コミットメッセージ内でチケットの参照/修正」で「refs」と「fixes」を使い分けると、SVNコミット時にチケットのステータスと進捗率を自動更新することもできる。

実際の運用は下記になる。

7-1.チケットの仕様を実装中だが、一旦コミットしたい

修正中のステータスなので「refs」を使って
「~の理由でコミット refs 123」
と書く。

SVNリビジョンとチケットにリンクが張られるだけ。
チケットのステータスも進捗率も変わらない。

7-2.チケットの仕様を全て実装完了した

修正完了のステータスなので「fixes」を使って
「~の機能を実装 fixes 123」
と書く

SVNコミット時に、チケットの進捗=100%かつステータス=解決に変更されて紐付けられる

この運用を入れた理由は、開発者がSVNコミット時にチケットのステータスを変更し忘れることがなくなるから。

もう一つの理由は、SVNコミットログに修正ステータスも入れたいから。
そうすれば、リリース後にSVNコミットログを集計した時に、「fixes」「refs」の単語で何かしらのソフトウェアメトリクスを採取できるのではないか、と思うから。

ソフトウェア・リポジトリ・マイニングでは、SVNコミットログの精度が高いほど意味のあるメトリクスを採取できるはず。

【8】RedmineからTestlinkへリンクを張る
 但し、ver 0.7以降に限る。

http://groups.google.com/group/redmine-users-ja/browse_thread/thread/aa2bf808a682756f

この記事によって、RedmineとTestlinkの相互リンクが可能になる。
Redmineでリソース管理、Testlinkでテストケース管理(要件管理)と使い分ければ、下記のように要件からソースコードまで一貫してトレースできる。

要件(Testlink)
←→テストケース(Testlink)
←→チケット(Redmine)
←→SVNリビジョン(Subversion)

 チケットとテストケースのトレーサビリティを提供する重要な機能。

【9】Redmineに機能追加するプラグインがある。
 最も興味を惹くのは、工数表示の拡張プラグインと、継続ビルド環境の実行結果を表示するプラグインだ。

Timesheet

Simple CI

 engineプラグインのインストールに何度も失敗したが原因は、./vendor/railsのバージョンが古いこと。
 一度削除して、Rails2.0.2をインストールすると、engineプラグインが正常動作する。

 Timesheetはあくまでも検索結果の一覧表示だけ。
 欲を言えば、日別・トラッカー別・マイルストーン別に工数をSVGでグラフで表示して欲しい。
 バーンダーンチャートを表示する機能も作れるはず。
 そうすると、プロジェクト内部で発生した工数をリアルタイムに見える化できる。

 SimpleCIは、Feed先のContinuum、CruisoCotrollの実行結果を表示するだけ。
 でも、これによって、テストケースはTestlink、常時統合ビルド環境はSimpleCI、ソース管理はSubversionという風に、Redmineでアジャイル開発のインフラが全てリンクされる。
 今の僕が一番欲しかった機能で、Redmineがプロジェクトの統合管理ツールになるための重要な機能と考える。

【10】メール通知の設定は、config/environment.rb で行う。

http://redmine.jp/faq/general/mail_notification/

この設定によって、チケットのステータスが変更されるイベントで担当者へメールが飛ぶ。
この設定が意味を持つのは、メンバーの人数が多くて担当者が頻繁に変わる作業。

特にバグ修正では、設計者・開発者・テスト担当者・管理者の間で1個のチケットが渡り歩くため、メール駆動でなければ、管理者が逐一指示しなければならない。

開発者が5人以上の場合はメール駆動でなければ、プロジェクトリーダーはメンバーの指示だけで1日の仕事が終わってしまう。

つまり、少人数のチームがメール駆動でBTSを運営すれば、プロジェクトの進捗を管理するだけの管理者は不要になりうる。

【11】信頼度成長曲線を描くプラグインがある。

Redmineのプラグイン (3) ゴンペルたん

turnkのソースで、チケットを登録したり、SVGプラグインを入れたりしたけど、うまく動作しない。。
ソースをいじるしかないかな。。

とはいえ、チケット情報はDBにあるから、Accessでクロス集計すれば信頼度成長曲線は書けるはず。
更には、バーンダウンチャートも同様に作れるはず。

信頼度成長曲線から品質の歩溜りが推測できるし、SRATSに食わせれば、ソフトウェア障害のMTBFまで計算できる。

SRATS

ここでのMTBFは、次のバグが発見されるまでの時間だから、例えば3ヶ月以上になるならば、リリースしても大丈夫だろう、などのような判断ができるはず。

プロジェクトリーダーとしては、信頼度成長曲線は、システムの品質が今どれくらなのか、後どれくらいでリリース可能な品質になるのか、を探るための重要な指針になりうると考える。

【12】プロジェクトメニューにリンクを追加する方法が下記に書かれている。

http://chocoapricot.cocolog-nifty.com/blog/2008/07/redmine_1316.html

http://groups.google.com/group/redmine-users-ja/browse_thread/thread/a7c9a244ede8b1ea

メニューにガントチャートを追加することも可能。
実際の現場では、ロードマップとガントチャートでリアルタイムに進捗確認したいので、ガントチャートもプロジェクトメニューにある方が使いやすい。

【13】「RedMineのチェンジセットの検索機能でユーザIDも検索対象にする」記事が下記にある。

http://d.hatena.ne.jp/snaka72/20080717/1216268311

上記の修正で、SVNの特定ユーザのコミット履歴を見ることもできる。

実は、検索ボックスに「#チケットNo」を入力すると、直接チケットを開くことができる。
非常にうまく作られていると思う。

Redmineの実際のDBをPhpMyAdminで見ると、すごく綺麗なDB設計。
しかも、Ajaxが効果的に使われていて、ユーザビリティも良い。

例えば、マイページがドラッグ&ドロップで簡単にカスタマイズできたり、チケット一覧で右クリックするとコンテキストメニューのようにステータスや担当者などを一括更新できたりする。

実際のリポジトリを見ると活発に更新されているので、次期バージョン0.8も楽しみだ。

| | コメント (0) | トラックバック (0)

2008/08/31

Redmine on JRuby

プロジェクト管理機能を持つBTSであるRedmineを愛用して運用して、技術的に気づいた点をメモ。

【1】RedmineをJRubyで動かす方法が下記の記事で紹介されている。

Redmineを運用するためのイロハを身につけよう
第7回 Javaプラットフォームでの運用

上記の記事は、Glassfish+JRuby上でRedmineを乗せている。

これは僕の中で最もホットな記事。
JRubyを使ってJavaアプリケーションサーバー上でRailsを安定稼動できるならば、Railsをビジネス用途で使う最大の不安が解消される。

一般のRailsアプリをTomcat上で動かすノウハウも下記で紹介されている。
仕掛けは、RailsアプリをWarblerでwarファイルにビルドして、JRuby+Tomcatで稼動させる。

Java屋がTomcatでRuby on Railsを試すには?
Warblerでwarのパッケージ化をしよう

ここまでのノウハウが現時点で公開されているので、おそらく来年はRailsを実案件で使うタイミングもあると思う。


【2】Redmine+Passenger(mod_rails)で、Apache上でRailsを稼動する方法が紹介されている。

Apache上でRuby on Railsアプリケーションを動かす
/Passenger(mod_rails for Apache)の利用

下記のコマンドを叩くだけで必要なライブラリがApacheにインストールされる。

gem install passenger
passenger-install-apache2-module

後は、httpd.confの設定だけ。
高負荷な使い方をしていないので分からないけど、結構安定しているし、レスポンスもいい。

Passengerの利点は、RailsがPerlやPHPと同じ感覚で運用できることだ。
Apacheは運用ノウハウや運用経験者が多いので、データセンターで運用する時にも利点になる。

今後のビジネスを考えると、業務アプリのRailsをJRubyで動かすか、Apacheで動かすか、どちらかが主流になると思う。
どちらも要注目の技術だと思う。

| | コメント (0) | トラックバック (0)

2008/08/28

CIツールHudsonを使いこなす

XPのプラクティスの一つが常時統合(CI・Continuous Integration)。
別名、デイリービルドと言われる。
第2世代CIツールと言われるHudsonを使って運用して、常時統合の概念について改めて書く。
#Hudsonの全機能はまだ使いこなせてないので念のため。

【1】バージョン管理(SCM)+常時統合(CI)+テスト駆動開発(TDD)で、初めてアジャイル開発が可能になる

【元ネタ】
バージョン管理と常時結合

豆蔵:継続的インテグレーション(CI)をしましょう

Subversionでbranches/tags/trunkでソース管理したら、次に行うべき環境構築はビルド環境。
Javaなら、Ant/Mavenでワンクリックでビルドできるようにスクリプトを作る。

今でもビルドする時に、Eclipseから手作業でビルドしているプロジェクトもままある。
ローカルマシンで手作業でビルドする弱点は、そのローカルマシンが使えなくなったらビルドできなくなること。
普通はプロジェクトリーダーがビルドとリリース作業を担当するから、彼の開発環境特有のノウハウがあったり、JDKのバージョンがマシンごとに違ったり、彼が夏季休暇でいなくなると、緊急リリースできなくなる。

だから、ビルド環境は開発サーバーで構築したい。
そうすれば、誰でもリリース可能になるし、誰がビルドしても同じバイナリのモジュールが作れる。
ビルドスクリプトもSVNでバージョン管理しよう。
そのビルドスクリプトに、JavaDoc生成、JUnit実行、各種レポート出力もあると、リリースするモジュールを作るだけでなく、納品ドキュメント一式も出力するといった作業も一発で自動化できる。

ビルド環境ができたら、SVNコミットするたびに常時統合するようにしよう。
常時統合の最大の利点は、SVNリポジトリがいつでもリリース可能である状態を保てること。

複数の開発者が一つのシステムを開発する時、インターフェイスが合わないことも知らずにSVNコミットする時がある。
常時統合するビルド環境があれば、ビルド後コンパイルエラーとしてすぐに通知できる。
更には、ビルド時に、コンパイルエラーだけでなく、テストユニットが全て通ることも必須にすれば、物理的だけでなく、仕様を満たすという意味で論理的にも正しいモジュールが作れることを意味する。
昨今のCIツールでは、画面上で結果を表示したり、メール通知したり、RSS表示などで通知してくれる。

つまり、常時統合の概念がないウォーターフォール型開発では、

コーディング→単体テスト→ビルド

の順に進んで、最後でエラーが分かるのに対し、常時統合環境ならば、ビルド時にJUnitを通過させることで単体テストも通ったプログラムかどうかチェックできる。

SCM+CI+TDDで初めて、プログラマ主体のアジャイル開発環境ができあがる。

【2】Hudsonはすごくお手軽で強力なCIツール

CIツールは、Continuum、CruiseControlなどあるが、第2世代CIツールと言われるHudsonを使ってみたらすごく使いやすい。
下記の記事が詳しい。

Hudsonを使ったアジャイルな開発入門

Hudsonの最大の特徴は、日本人技術者が作っているので日本語化されていること。
又、warファイルで提供されているので、Tomcatへデプロイすればすぐに操作できるのでインストールが簡単。

上記の記事を読みながら、まだ使いこなせてないが、興味深い機能について下記にまとめる。

【3】Hudsonの特徴~ビルドプロモーション


Hudsonを使ったアジャイルな開発入門
第4回 プラグインを使う
ビルドプロモーションとプラグイン

Hudsonを使ったアジャイルな開発入門
第4回 プラグインを使う
シナリオ

大規模プロジェクトで複数の開発チームでビルドしているとする。
その場合、複数のビルドモジュール(例えば、jar又はWindowsのDLL)を作り、それらを一つの実行ファイル(例えば、war又はWindowsインストーラ)にまとめることが多いだろう。

大規模プロジェクトの成功が非常に難しい理由の一つに、ビルドプロセスがうまく運用できない点がある。
例えば、チームAが作ったライブラリにインターフェイス追加の仕様変更があったのに、他チームが対応していなければビルド時にコンパイルエラーになる。
でも実際は、新規のインターフェイスに対応するのは後回しでも良い時があったりする。
チーム間のコミュニケーションで風通しが悪いと、よく起こる。

あるいは、バグ修正や仕様変更などでインターフェイスが大きく変わってしまったけれど、他チームでは、一部の新しいインターフェイスだけ欲しい時がある。

また、ビルドを通した時に、ビルドは成功するがいくつかのUnitTestは通らないけれど、そのビルドモジュールが他チームでは開発上必要な場合もよくある。

そんな時に、ビルドプロモーション機能を使う。
つまり、ビルドモジュールに、優良・不良・最終用などの状態で色付けする。
Hudsonでは、ファイル指紋という機能があり、ビルドモジュールを一意に峻別してバージョン付けすることもできる。

特に昨今のWebシステム開発はスピード重視なので、完全なビルドモジュールでなくとも、一部のインターフェイスが通るだけのライブラリがあれば、サクサク開発できる時も多い。

上記の記事では、下流ビルドのチームが上流ビルドのチームへ、これこれのバグを修正したモジュールだけ欲しいと依頼して、ビルドしたライブラリを作ってもらうという話がある。
そんな時に使えるだろう。

【4】Hudsonの特徴~分散ビルド

Hudsonを使ったアジャイルな開発入門
第3回 Hudsonによるチーム間の連携
分散ビルド

ビルドするライブラリが多くなると、最終形式のリリースモジュールを作るまでに1時間近く実行時間がかかる時がある。
特に大規模プロジェクトほどそうなるだろう。
ビルドに時間がかかると、開発者はソースコミットが慎重になり、プロジェクト全体の活動が低下して進捗がどんどん遅れる。

Hudsonには分散ビルドという機能があり、複数のビルド環境と連携して、ビルド作業を並列に実行することができる。
つまり、ビルド作業を直列ではなく並行実行することで、見かけ上のビルド時間を減らす。

詳細な設定方法は上記の記事に書かれているが、大規模プロジェクトでは非常に有効な機能だ。
特に昨今のWebアプリのように、クライアントアプリとサーバーアプリで共通ライブラリをくくりだしてビルドする場合、たった1行のソース変更で、ユニットテストも通すからビルドが1時間かかることも稀ではない。
サーバーはとても安くなったので、古いサーバーをビルド環境にして並列ビルドできれば、複数のチームによる開発でもアジャイル開発できるはずだ。

【5】Hudsonの特徴~マルチ構成プロジェクト

Hudsonを使ったアジャイルな開発入門
第5回 高度なプロジェクトタイプ
マルチ構成プロジェクト

この機能は、ハードウェアやJDK等のバージョンは違うけれど、同じビルド作業を行う時、同一のビルド設定情報を使って、複数の環境でもビルドできるようにすること。

本番環境のJDKのバージョンアップ、ハードウェアのリプレースでOSなどの環境が変わった時、この機能を使えば、Hudsonが色んな構成方法でビルドして結果を出力してくれる。

特にWindowsアプリのように色んなOSでビルドできることを確認したい時、あるいは、WebアプリでJDKのバージョンアップしてもきちんとビルドできるかを試したい時に使えるだろう。

ハードウェアやJDKのバージョンアップは、長期間続くプロジェクトでは避けられない。
だから、Hudsonの上記の機能は非常に使える。

【6】HudsonとBTSを連携する

昨今のBTSではコミットログにチケットNoを書くと、BTSチケットとソースリビジョンが紐づけできる環境がある。
Hudsonでも、ビルド結果にソースのコミットログを表示するので、プラグインを入れると、コミットログのチケットNoからBTSへリンクする機能がある。
これはすごく便利だ。

TracLightningでは、Hudsonが既に組み込まれている。
他にも、Bugzilla、Mantis、Trac、JiraなどのBTSと連携するプラグインがある。
残念なことに、RedmineはHudsonと連携するプラグインがない。
単にURLを設定するだけなので簡単だと思うが。。

常時統合という概念を生み出したXP
CIツールとBTS、バージョン管理を上手に使えば、アジャイル開発を簡単に楽しく実現できるはずだ。

| | コメント (0) | トラックバック (0)

2008/08/23

Naoyaさんのトークセッション

Naoyaさんがジュンク堂で「私と技術書」を講演された感想をメモ。
#印象深い部分だけの感想なので注意。

ジュンク堂書店大阪本店 トークセッション情報

【1】可用性、信頼性などのキャパシティ管理はLinuxカーネルのソースコードから解析する

Naoyaさんのキャリアを初めて聞いた。
Perlを中心としたWebプログラミングを中心にやってきて、はてなの最高技術責任者になって、負荷分散の技術に随分悩んだ話が興味深かった。

今までは、サーバーの負荷が高い時、どのような対処をすればよいか、対症療法しかできなかった。
だから、パッチのような対処しかできず、ずっと悩んでいた、と。

詳解 Linuxカーネル」などを読んで、仮想メモリ、マルチタスク、I/Oディスクなどの仕組みがソースレベルで分かった。
Linuxカーネルの動きをソースコードレベルで追えたからこそ、何故負荷がかかるのか、理由をもって説明できて対策できる。
本の文章に嘘はあっても、ソースコードに嘘はないから、と。

その辺りのノウハウも含めて、「サーバ/インフラを支える技術」という本を書きました、と。

※補足:「Linuxカーネルの読み方」というスライドシェアが公開されている。

http://www.slideshare.net/naoya1977/how-to-read-linux-kernel/

サーバ/インフラを支える技術」では、飛び道具のようなノウハウよりも、ローレベルのLinuxカーネル、ハードの計算機部分まで関係しているという部分に力を入れて書いた。
だから、著者が一番力を入れた部分を読み取って欲しいし、この本で全て書いているわけではないが、この本を手がかりにして探って欲しい、とのこと。

昨今のWebシステムが旧来のメインフレームより劣っていた部分は、運用保守にあったと思う。
何故、Cobolのような古い言語がいまだに使われているのか、という理由は、可用性や信頼性が抜群に安定しているメインフレーム上で動くからだ。
いわゆるオープン系のWebシステム、クラサバのシステムは、プログラミングという開発の生産性は抜群に素晴らしいが、24時間365日安定稼動、99.9999%の信頼性という運用保守では、20年以上ノウハウを貯めてきたメインフレームにはまだ劣るだろう。

しかし、「サーバ/インフラを支える技術」という本が出てきたように、Webシステムでも、負荷分散や安定稼動させる運用ノウハウは、以前に比べると随分たまってきたように思う。

メインフレームは大手SIer独自のハードウェアゆえ、その中身はユーザも他の開発者も知りえない。
それに対して、Webシステムが動作する殆どの基盤はLAMPを中心としたオープンソースだから、技術力さえあれば誰でも読める。
LinuxやApacheのソースコードを理解できれば、何故CPUの負荷が高いのか、メモリがオーバーするのか、その原因を突き止めるログや統計結果を自分で作ればいい。

Naoyaさんの話で興味深かったのは、OSの仮想メモリ、マルチタスク、マルチスレッドの動きは、本で書かれた概念と実際のソースに書かれている動きに違いがある、という話。

この辺りの感触も実際にソースを読んでみないと分からないのかな、とも思う。

【2】WebプログラミングからローレベルのLinuxカーネル、計算機科学、そして科学へ

最近のNaoyaさんの興味の話も目を引いた。
最初はPerlなどのWebプログラミングしか知らなかったけれど、ローレベルのLinuxカーネルを知って、負荷分散という技術にも強くなった。
そのおかげで、プログラムという抽象レイヤーのメカニズムも透けて見えるようになった。
今は、もっと深い部分であるコンピュータという計算機がどのように動いているか、という計算機科学に興味が向いている、と。

だから、今、はてなでは計算機科学のセミナーを開いている、とのこと。

NaoyaさんのようなハッカーがWebプログラミングの上層からLinuxカーネルや計算機科学のような下層へ深く掘り下げていく方向へ興味が向いていく話とその経験談がすごく興味深くて面白かった。

情報系の学部で勉強している人なら下層から上層へ進むのだろうが、NaoyaさんのようにWeb開発の経験が豊富な人は上層から下層へ掘り下げていく方が、自分の経験が理論化されて整理されていくだろうから楽しいだろうな、と思う。

プログラム開発と違うサーバー運用保守であっても、やはりプログラミング技術が基本なのだ、と改めて認識させられた。

| | コメント (0) | トラックバック (0)

2008/08/11

ブロックはRuby流無名関数

Rubyのブロック、ブロック呼び出しで参考になる記事があったのでメモ。

【元ネタ】
Rubyのyieldを使った例を教えてください

yieldはブロック呼び出しに使うとのことだが、コレクションの値の総和や二乗和を求めるコードの例が凄い。

無名関数を渡す発想はオブジェクト指向ではないと思う。
関数型言語の発想だ。

| | コメント (0) | トラックバック (0)

2008/08/10

ソースインスペクションを真面目にやるGoogle、MS

GoogleやMSがソースコードレビューを真面目にやっている下記の記事を何度も読んで、ソースコードレビューシステムを何とか導入できないか模索している。

【元ネタの記事】
Googleのコードレビュー

MS内部のソフトウエア開発手法の話

Review Board - コードレビューをオンラインで

VMWareの開発でも利用されているソースコードレビュー共有ソフトウェア「Review Board」


ソースコードインスペクションの重要性は、二人の目による品質管理だけでなく、設計思想を共有する重要な手段と捕らえるべきだと思う。
プログラミングは誰でも癖があり、時に品質をすごく落とす。

だから、他の人に手軽に見てもらい、チャットのようにレビューをコメントしてもらうようなスタイルにしたい。
そうすれば、ソースインスペクションという技術者同士で熱くなりがちな議論を会話するような雰囲気に持ち込みやすいから。

他の記事で、特に気になった言葉は下記2つ。

「レビューは不具合をみつけるのではなく、信頼感を醸成するためのものだ。」
「レビュー(ピアレビュー)はペアプログラミングの代替である。」

コードレビューの利点は、品質の確保だけでなく、チームメンバー全員がコードの思想を共有することだと思う。
コードレビューによって、若手のスキルは確実に上がる。

コードレビューシステムに関しても、オープンソースの開発者の方が大手SIerよりもレベルが高い気がする。
オープンソースの方がソースインスペクションのプロセスも洗練されている。

オープンソースでは、特にパッチや機能追加のソースはコミッタが必ずレビューして、どのバージョンに入れるか判断を下す。
例えば、Matzさん、ひがやすをさんのような世界トップレベルのコミッタが、送られたパッチをコミットするかどうか判断するのだから、普通の大手SIerよりも技術レベルが当然高い。

他に、分散ソース管理(例えば、Gitなど)が普及しつつある理由の一つに、コミッタ権限の無い開発者がハックするのに使うこともあげられる。
つまり、ローカルのリポジトリに自分がハックしたソースをコミットして履歴を残せる。
マスタリポジトリから定期的にローカルリポジトリと同期すればいい。

この時、マスタリポジトリにコミットする前に、ソースインスペクションで癖のあるソースを直すのにこのコードレビューシステムを使いたい。

コードレビューシステムとしては、ReviewBoardが使いやすそう。
ReviewBoardはPythonでインストールが面倒だが、Webでレビューコメントを気軽に書けるので導入してみたい。

Web2.0のシステムは、SNSのように足跡のような機能が豊富。
つまり、誰かがコミットした、チケットにコメントした、という作業ログをシステムが自動巡回してその統計結果を多角的に集計して表示することが可能なのだ。

この機能は、特に小売系Webシステムでは、マーケティングの一手法として、リコメンドエンジンのような複雑なアルゴリズムなどで実装されている。

Web2.0のそんな機能をプロジェクト管理に使えないだろうか?

(その答えは、ソフトウェア・リポジトリ・マイニング)

| | コメント (0) | トラックバック (0)

2008/06/09

Googleのアーキテクチャ

Googleのソフトウェアの3つの中核となる要素、「GFS(Google File System)」「BigTable」「MapReduce」に関する記事があったので、メモ。

グーグルデータセンターの内側--明らかにされた独自性 2

そのアーキテクチャの特徴は、並列処理とフォールトトレラント(耐障害性)。
もはやハードウェアは使い捨て。
ソフトウェアで冗長性まで実現してしまう。

次世代スーパーコンピュータ施設の立地地点を神戸に決定」という記事があったけれど、時代とマッチしていないように思う。
安いサーバーを1万台、並列処理させた方がコスト的にも速くないだろうか?

恐るべしGoogle。

| | コメント (0) | トラックバック (0)

2008/06/02

MapReduceメモ

MapReduceの説明で良い記事があったのでメモ。

下記2つは、丸山先生の解説。
短いけれど、本質を突いている。

[jjug-members] MapReduceのアルゴリズム

[jjug-members] MapReduceのアルゴリズム2

下記は、オープンソースのGoogleクローンHadoopの解説。
丁寧ですごく分かりやすい。

Hadoop、hBaseで構築する大規模分散データ処理システム ~[初級] Google基盤ソフトウェアのオープンソースクローンを使ってみる 1

MapReduceの計算モデルが威力を発揮する状況は、1テラバイトのテキストファイルの読み込みや膨大なバッチ処理など、コンピュータのメモリにロードできない場合。
Map→ソート→Reduceという単純なアルゴリズムで、DVD1枚のGrepを0.2秒で処理しきってしまう威力。

プログラミング設計の基本パターンは分割統治。
その代表例としてオブジェクト指向設計がずっと叫ばれてきたが、いい加減飽きた。

もう一つの分割統治のパターンは、関数型言語やUnixのPipeAndFilterのように、膨大な処理を小さなプロセスに分割して並列に走らせること。
今後のプログラミング言語は、並列計算を実現できるような仕組みが必要だろう。

並列処理が有効に効く状況は、マルチコアCPU、Webネットワーク、バッチ処理など。
つまり、組み込み系でも、業務系でも、今後、関数型言語の発想によって、アーキテクチャが今と根本的に変わる可能性がある。

| | コメント (0) | トラックバック (0)

2008/06/01

【感想】Kansai.pm第9回ミーティング

Kansai.pm第9回ミーティングに行ってきた。
その感想を書く。

【1】Naoyaさんの話~Hadoop Streaming で MapReduce

はてなのNaoyaさんの話。
一番興味があったが、期待通りすごく面白かった。

MapReduceとは、GoogleLabの論文に書かれた分散処理の高速アルゴリズムの一つ。
並列計算アルゴリズムの一種で、Googleが使っている。
Googleはこのアルゴリズムを使って、大規模データを多数のサーバーで並列処理させている。
つまり、バッチ処理を高速化したものと言える。

MapReduceのアルゴリズムのイメージは下記のようにすごく簡単。

入力ファイル→map()→シャッフル→reduce()→出力ファイル

つまり、計算モデルは、関数型言語の特徴である「map:写像」「reduce:畳込み」の2個の関数を組み合わせただけ。
これは、UnixのPipe and Filterと同じ発想だ。

但し、並列処理させるために、分散ファイルシステムが必要。
Googleは、独自の分散ファイルシステム(GFS)を持ち、これが強力。
特に、冗長性に特徴がある。

例えば、1テラバイトのバッチ処理のために、1テラバイトのデータをネットワーク転送するのは、非常に不安定。
ネットワーク転送するだけで1日以上かかるだろう。
GFSというGoogleの分散ファイルシステムは、1 TBを64Mbにchunkして、その単位でワーカーに処理させている。
また、壊れたノードは、別のノードが引き継ぐなど、フォールトレランス機能もあるらしい。

詳細は下記を見よ。

http://www.radiumsoftware.com/0608.html

ここに興味深い一文がある。

関数型プログラミングを会得しない限り, Google に強大なスケーラビリティをもたらしたアルゴリズム ― MapReduce を発明することはできないだろう。 -- Joel Spolsky [Joel]


MapReuceの利点は、計算アルゴリズムがmap, reduceだけでいいという簡単さ。
つまり、巨大なデータを細かい処理に分割し、透過的に処理させる。
その実装プログラムは、ストリーム的な処理で解けるため、関数型言語でなくとも、大抵のプログラミング言語で実装しやすい。

MapReduceで解ける問題としては、検索エンジンのインデックス作成、ソート、検索結果のPageRankの計算、ドキュメント内のリンク参照回数の計算からWebページの有用度計算、など非常に応用範囲が広い。

つまり、Googleは、このアルゴリズムを使って、検索エンジンのインデックス作成を高速化しているのだ!

例えば、MapReuceを使うと、DVD1枚をGrepするのにわずか0.2秒で処理できるらしい!!!
(ただしタスク分散のオーバーヘッド有り)

Naoyaさんは、MapReduceという分散処理の高速アルゴリズムを使って、Perlで実現したらしい。
話した内容の詳細は下記と殆ど同じ。

http://d.hatena.ne.jp/naoya/20080511/1210506301

※講演資料が下記で公開されています。

http://d.hatena.ne.jp/naoya/20080531/1212245982

Naoyaさんは、Googleの論文を読んで、Perlで独自実装したらしい。
使い道としては、巨大なApacheログ解析や検索インデックス作成など。
膨大なテキストファイルを1日ぐらいかけて読み込んでバッチ処理するのを高速化するのに向いている。

後で聞いたら、MapReduceには結構バッドノウハウがあるそうで、分散ファイルシステムだけでなく、シャッフルやReduceなどの処理で色々アレンジするらしい。

【2】バッチ処理の高速化が意味するもの

バッチ処理は業務システムの基本アーキテクチャだ。
特に金融系システムでは、毎日数万~数十万のトランザクションデータをバッチで一括処理するのも稀ではない。
この処理の実装は簡単であろうとも、テストして品質を確保するのは非常に難しい。

何故なら、高負荷な環境でしか再現できないバグは結構あるのに再現させにくい。
また、バッチ処理が異常終了した時、全件ロールバックさせると更に負荷がかかる。
だから、100件おきにチェックポイントを区切り、途中までCommitを実行し、途中から再開できるような仕組みを作る必要がある。

つまり、バッチ処理は、高負荷な環境のシステムテストや異常処理の設計がかなり難しいのだ。
しかし、Googleが適用しているMapReduceモデルでは、GFSというGoogle独自の分散ファイルシステムを使って、壊れたノードは別のノードが引き継ぐという冗長性を確保している。
並列処理なので、プロセスが死んでも他プロセスが引き継げばいい。

Naoyaさんも言っていたが、バッチ処理は冗長性が非常に大事。
いわゆるフォールトレランスが大事なのだ。

【3】日本のSIerの現状

上記の話を聞いて、非常に驚いた。
関数型言語の計算モデルがバッチ処理を抜本的に変えたとも言える。

日本の大手SIerのプログラマ、プロジェクトリーダーは、マンパワーでシステム開発し、マンパワーで品質を確保しようと懸命になっている。
Googleは、システム開発の前提条件そのものをひっくり返して、画期的アーキテクチャで作り直している。
当然、品質確保のやり方も日本のSIerと全く違う。

はてなのNaoyaさんは、少なくとも、Googleの論文を読んでいる。
日本の大手SIerにいるプログラマ、プロジェクトリーダーで、Googleの論文を読んでいる人はいるだろうか?
皆、残業に追われて、デスマーチに追われているうちに、Googleが生み出した技術などに取り残されている。
自分の技術が古くなっている事実にも気づかずに。

はてなは日本のGoogleみたいだ。

| | コメント (0) | トラックバック (0)

2008/05/29

オブジェクト指向言語と関数型言語の書き方の違い

【1】オブジェクト指向言語の書き方は「set-do-get」

複数の引数を渡して、価格を計算する処理を実装するとしよう。

手続き型言語なら、下記のようなシーケンス図になるように書くだろう。
つまり、1個の関数にたくさんのロジックを詰め込む。

C


例えば、Cのmain関数のように、1個だけの関数にロジックを詰め込んで、下手をすれば数千行に及ぶソースになる。
そうなると、もはや保守していくうちに、誰もが修正できなくなる。

オブジェクト指向言語なら、下記のようなシーケンス図になるだろう。
つまり、1個のクラスに必要な情報をsetし、状態を変化させて、必要な情報を最後に取得する。
副作用を起こす関数(set, do)と副作用の無い関数(get)を使い分ける。

いわゆる「set-do-get」の書き方。

Java

オブジェクト指向に基づいて綺麗に設計したシーケンス図は、階段状のシーケンスになることが多い。
つまり、複雑なロジックは、各クラスへ適切な粒度で分割される。

例えば、購入した商品の計算は、商品の価格と個数だけでなく、内税や外税のような消費税計算、あるいは、ポイントを使った割引など計算ロジックが複雑になりがち。

更に、会員が上得意か新規かという会員区分、あるいは、ギフト商品や優待会員向け商品など商品によって計算ロジックを動的に変えたい時が発生する。

だから、計算クラスを更に分割するなどのクラス設計をするのが普通。
この時に、ポリモルフィズムを使う。

Javaでは、ポリモルフィズムをState/Strategyパターンで実現する。
この時に、継承構造を使うことが多い。
そして、機能追加や保守していくうちに、継承構造が深くなり、サブクラスから親クラスをコールするような依存循環構造が発生して、手に負えなくなってくる。

Ajaxのような関数型言語の出現によって、オブジェクト指向によるポリモルフィズムは限界があるのではないか、と最近感じる。

【2】関数型言語の特徴~クロージャと継続

プログラミングGauche」では、関数型言語Schemeの最も基本的なルールは下記の2つだと喝破している。

2-1.lambda式は「レキシカルな環境を保持した手続き」(クロージャ)へ評価される。
2-2.手続き呼び出しは継続を使った引数付きgotoである。

クロージャの例として僕が分かりやすかったのは、クイックソート。
C言語で実装したクイックソートの関数では、ソート関数を関数ポインタとして引数で渡す。

PerlやRubyでは、テキストファイルを読み込んで、ゴニョゴニョ処理するロジックでクロージャを使う時が多い。

プログラミングGauche」では、「継続とはプログラムのその時点より後に行う計算」と説明している。

継続の使い道は、Webアプリなら、ログインチェックだ。
つまり、ログインに失敗して、再入力してログインに成功したら、途中まで読み込んだ処理の途中から再開して実行する。
更に、Webアプリで継続が使えれば、いつも問題になる「戻るボタンの遷移」が簡単になる。

クロージャと継続を使って、ポリモルフィズムを実現できないか?
つまり、複雑な条件分岐を、クロージャと継続を使って、もっとエレガントに書けないだろうか?

関数型言語でポリモルフィズムを実現する手法は、リフレクションだと思う。
複雑なループ処理、深くネストしたIF文などの制御構造そのものを一つの手続きに抽象化する。
IF文の判定式、条件分岐後の実行ロジックは、リフレクションで後から動的に決める仕組み。

関数型言語は、手続き型言語やオブジェクト指向言語と書き方がまるで違う。
もっと研究する余地がある。

| | コメント (0) | トラックバック (0)

2008/05/26

オブジェクト指向の次の思想は?

【1】オブジェクト指向という概念は、20年以上叫ばれてきた。
でも、正直、聞き飽きた所がある。

オブジェクト指向を生かした設計手法であるUMLも、以前よりもコミュニケーションが取りやすくなったが、所詮ダイアグラムに過ぎない。

オブジェクト指向開発プロセスの集大成であるRUPは、もはや馬鹿でかい開発プロセス。
誰もそれを完全にマスターすることは難しい。

プログラミング技術では、オブジェクト指向の最大の利点はポリモルフィズムだ。
一つの型(インターフェイス)を複数のインスタンスで動的に振る舞いを変える仕組み。
Javaでポリモルフィズムを実現するには、普通は継承を使う。

デザインパターンはオブジェクト志向のカタログ。
デザインパターンは、C++のベストプラクティス。
Javaもそれを引き継いでいる。

ポリモルフィズムを使いたい状況は、複雑な条件分岐。
いわゆるswich文、IF文が羅列しているプログラムを、複数のクラスへ分割する手法。

特に、業務システムは、業務の状態判定をフラグとIF文で実装していくうちに、IF文がどんどんネストして深くなって、誰も修正できなくなる。

状況に応じて、下記3つのデザインパターンを使うのが普通だろう。
それぞれの条件分岐のクラスのインスタンスは、FactoryかAbstractFactoryクラスで生成する。

1.switch文やIF文の状態判定から、状態やアルゴリズムを抽出する
→State/Strategyパターン

2.swich文で二つの型を比較して条件分岐したい時(いわゆるマトリックス型分岐)
→Visitorパターン

3.それぞれの条件分岐のアルゴリズムを組み合わせて、最大値や最小値を取り出したい時。
 State/Strategyパターンの変形と言える。
→Decoratorパターン

継承構造が複雑な場合、継承構造を複数のビューから眺めて2つの継承構造へ分離するBridgeというデザインパターンもある。

でも複雑性に対応しきれなくなっている。
一度、継承構造を入れてプログラミングすると、機能追加していくうちに、継承が深くなりがち。


【2】最近、Ruby、JavaScript、Scalaのようなスクリプト言語や関数型言語に触れて、ポリモルフィズムの実現方法が変わってきている気がする。

うしおさんの記事「私がScalaを選んだ理由 [初級~中級] JavaとRubyとScalaの比較」を読んで、その理由が少し分かった気がした。

結論から言うと、RubyやJavaScriptは、Javaと書き方が違う。
それは、関数型言語の発想と言っていいと思う。
その特徴は二つあると思う。
一つは、リフレクションを多用したメタプログラミング。
そしてクロージャ。

例えば、条件分岐はリフクレクションで極限まで共通化する。
それができるのは、スクリプト言語という特徴があるから。
型にとらわれないからできる。

Railsはmethod_missingという特徴がある。
これは、メソッドが無ければ勝手に生成してくれる。
正規表現が強いRubyらしい。
Railsはリフレクション使いまくりだ。

他にも、メソッドチェーン、短絡評価など。

ループ処理はクロージャで簡略化して書ける。
Javaなら、無名関数や無名クラスを作るのが面倒だが、スクリプト言語は、関数がファーストクラスなので、関数をプロパティのように扱える。

これらの性質を使うと、継承構造を使わなくとも、フレームワークが後で動的にメソッドを追加して、機能を増やすことができる。

JavaVM上で動く関数型言語Scalaでは、Implicit conversionsという機能がある。
これは、型を拡張する方法。

Implicit conversionsはまだ理解し切れていないけど、これを使うと、型を変更すること無しで、パッチのようにメソッドを追加できる。

詳細は、keisukenのHPを見よ。

そこでは、PersonクラスにImplicit conversionsを当てると、RichPerson.ageのインターフェイスを実行できる。
Personクラスには、ageインターフェイスはないのに!

【3】今まで手続き型言語の日陰に隠れていた関数型言語がにわかに存在感を増してきた理由は、WebとマルチコアCPUの普及だと思う。

WebもマルチコアCPUも、並列処理、分散処理に特徴がある。

今まで、1個のCPU上で、マルチスレッドに気遣いながら手続き型プログラミングしてきた。
でも、マルチコアCPUでは、ロジックを複数のプロセスへ分解して、プロセスを平行に走らせるようプログラミングする。

Webプログラミングも同じ。
複数のクライアント、複数の画面から飛んでくるリクエストの状態を保持する機構は、セッションしかない。
セッションはグローバル変数と同じ。
昔のデスクトップアプリのメモリリークと同じ問題構造を持つ。

プログラミングErlang」では、こんな一節がある。

なぜマルチコアCPUを気にするのか?

(中略)
デュアルコアマシンでプログラムが2倍以上速くなっても深い意味はない。

(中略)
2倍の高速化くらいでは驚かないにしても、10倍なら話は別だ。それが100倍なら本当にすごいことだ。

今日のプロセッサは高速で1つのコアで4つのスレッドを並列に実行できるので、32コアのCPUならば128個分のスレッドを使える可能性がある。
つまり、100倍の高速化も射程内にあるということだ。
100倍高速になるなら黙ってられない。
実現するにはコードを書けばいいだけだ。


そう、今のJavaに不満があるなら、コードを書けばいいだけだ。

| | コメント (0) | トラックバック (0)

2008/04/22

WebブラウザのJavaScriptエンジン高速化がもたらすもの

「SaaSに追い風、桁違いに速い次世代Webブラウザたち」の記事を読んだ感想。

Ver3のFireFox、Safariは性能がすごくいいのは知られていた。
その秘密は何か?

そもそもWebアプリの弱点は、一つはネットワーク遅延で応答性が悪いこと。もう一つはHTMLコンテンツを動的に扱うJavaScriptエンジンが遅いことだった。

しかし、前者は、Ajaxと総称される非同期通信のテクニックが進化したことでほぼ解消されつつある。
Googleが編み出すサービス群がその良い例。

後者は、次世代Webブラウザに搭載されるJavaScriptエンジンが高速化することで、今後解消されていくだろう。

そして、それは何をもたらすか?

近い将来、殆どのデスクトップアプリはWebアプリへ置き換わるだろう。

例えば、Google Docsの表計算アプリケーションは、Web上でExcelっぽく使える。

メールソフトも今やGMailを使う人が殆どではなかろうか?
GMailならば、外出先でも携帯からでも閲覧できる。

上記2点とも、Ajaxによる非同期通信のおかげで、ネットワーク越しの応答の遅延が気にならなくなったということ。
ユーザがブラウザで閲覧している裏で、Ajaxが必死になってDOMを生成して、HTMLをレンダリングしている。

利点は、ネットワーク上の人たちと情報共有がすごく簡単になることだ。
使いこなせれば、もっとコミュニケーションを活発化できる。

| | コメント (0) | トラックバック (0)

2008/04/16

Javaで型推論をプログラミング

Javaの型推論Utilsクラス」の記事から。
Javaでも型推論できるのか~。

でも、C言語のように、やたらとカッコ付きの型キャストが多い。
Scalaの方がいいのだろうか?

| | コメント (0) | トラックバック (0)

2008/04/13

【感想】第25回Ruby勉強会

大阪国際大学で開かれた第25回Ruby勉強会の感想を書く。

【1】JavaEEでRailsを動かす

紅月さんの講演
一番興味があった。

理由は、ファウラーの下記の記事「ファウラーがRubyに抱く感慨」が気になっていたから。


(前略)若いテクノロジーには新しくて重要な特筆すべき点がいくつもある。だが、私にとって最も重要なのは、JRubyだ。現在、JRubyは最終的なRCの段階だ。 Java VM上で動くスクリプティング言語を提供するだけでなく、 Rubyプラットフォームの完全な実装をJVM上で行おうとしている。 ThoughtWorksで我々が行っていること、そして、多くのRuby/Rails開発者たちにとって、(たとえ"include java"をしたことがなくても)これはかなり重要なことである。

我々のRubyチームが開発中に直面した最も大きな問題はデプロイだ。 Rubyのアプリケーションを実践投入するには、非常に多くの新しいテクノロジーが必要となる。それに、データセンターはこういったことに保守的だ。我々のRubyWorksもこの点をシンプルにしようと努力している。 JRubyはこの点について、Javaコンテナにデプロイすればよいので、 Railsアプリケーションもwarファイルとして簡単にデプロイできると主張している。これにより、Ruby on Railsが多くのエンタープライズ環境における選択肢となる得るのではないかと私は思っている。(後略)


Rubyはスクリプト言語なので、プログラムそのものがアプリケーション。

でも、本来、プログラムの目的は、実行可能なバイナリモジュールを作ることにある。
Cobol、C/C++からJava、C#へ至るプログラミングの歴史と同じぐらい、ビルドの歴史も長い。

例えば、Windowsアプリは、小さな実行モジュールであるexeファイルと、複雑な業務ロジックや共通ライブラリを分離した複数のDLLから構成されるのが普通。
その思想は、プログラムを論理的に分割するだけでなく、物理的にも分割し、複雑性を制御しようとする所にある。

同様に、JavaのWebアプリも、war/earファイルという一つのWebアプリをAnt/Mavenでビルドして作る。
warファイルの構成は、JSPなどのViewがrootの直下に配置される。
Controllerが含まれるWEB-INF。
そして、複雑な業務ロジック、共通ライブラリは複数のjarファイルへ分離する。

Windowsアプリと同じく、この設計思想も、複雑なプログラムを物理的にjarファイルへ分割するやり方に受け継がれている。

だから、RubyやRailsの弱点はビルド&デプロイにあるのではないか?というファウラーの指摘は的を得ている気がする。

紅月さんが紹介してくれたやり方の発想は、下記の仕組み。

Rails(warファイル)

JRuby

RailsServlet

Servlet Container(Tomcat等)

JVM

つまり、RailsServletがRailsをServletコンテナにラッパーして、Tomcat上で動かせるようにする。

RailsをTomcatで動かす利点は、JavaのWebアプリケーションサーバーは枯れた技術で性能もいいから。
Tomcat上でRailsが動けば、JBossを初めとして、WebSphere、WebLogicのような大規模なJavaのWebアプリケーションサーバーでも動作可能になるだろう。
そうなれば、より大規模で複雑なWebアプリをRailsで作ることが容易になるだろう。

紅月さんのデモはうまく動作しなくて残念だったけれど、この思想はファウラーの指摘以外にも、もう一つの重要な指摘を含む。

それは、JVMがインフラであること。
JDK6以降では、JRubyだけでなくJavaScriptのような殆どのスクリプト言語がJVMで動作可能になっている。
つまり、JVMさえあれば、RubyもPythonもJavaScriptも動いてしまうのだ。

最近は、Scalaのような関数型言語さえJVMがあれば動作する。
このScalaは、Liftという興味深いWebフレームワークもあるようだが。

実際はパフォーマンスもあろうが、特にWebシステムはスケールアップしやすいので、近い将来、JVM上でRailsを動かすのも実用的になるだろう。

まだ、Tomcatの上でRailsを動かすのは不安定だが、要注目の技術だと思う。

【2】角谷さんのRSpecライブコーディング

 角谷さんは本来、関西人だったそうで、ライブコーディングでは関西弁が随所に出て、聞いていて楽しかった。
 僕自身はJUnitに慣れているので、RSpecよりもRubyのTestUnitの方が理解しやすい。
 yu-yaさんに尋ねたら、TestUnitの方がassertEqualsだけで書けるので簡単ですから、と言っていたのが印象的だった。
 
 角谷さんが、ユニットテストのプログラミングの重要性を下記の図で説明した。
#縦軸:ソースの綺麗・汚い
#横軸:プログラムが動く・動かない

┌─────┬───┐
│       │     │
│ お花畑  │理想  │
│       │     │
├─────┼───┤
│       │     │
│ 終了   │現実  │
│       │     │
└─────┴───┘


 つまり、理想は、綺麗で動くプログラム。
 でも、現実は、動くけれど汚いプログラム。
 
 綺麗だけれど動かないプログラムは、お花畑。
 汚くて動かないプログラムは、既に終了している。

 角谷さんによると、リファクタリングとは、終了→現実→理想へのルート。
 
 池上さんは、終了→お花畑→理想 のルートもないだろうか?と質問していた。
 角谷さんによる明示的な回答はなかったけれど、数学者である池上さんらしい指摘。
 Haskellはまさに、コンパイルが通れば確実にバグなしで動く。
 Haskellは、終了→お花畑→理想 のルートなんだろうな。

 今日のRuby関西は、Flexユーザーグループ関西の夜桜と重なり、ちょっと人が少なかったのが残念。
 でも、懇親会、2次会も盛り上がって楽しかったです。

 ちなみに、角谷さんの本にサインしてもらいました。
 角谷さんの本は下記が有名かなぁ。


| | コメント (0) | トラックバック (0)

2008/04/07

ハムスターDBはSQLLiteの代わりになるか?

ハムスターDBが可愛い(^^♪
SQLLiteのように、お手軽なDBとして使えるだろうか?

| | コメント (0) | トラックバック (0)

2008/04/05

最近はプログラマの影響力が大きくなっている

最近のWebシステムの開発の現場で気づいたこと。
システム開発の現場でプログラマの影響力が大きくなっている気がする。

現在は、入社1年目の新人プログラマでも、3ヶ月で軽く数万行のプログラムを書いている。
優秀な人であるのは分かっているが、数年前には信じられない状況だ。

数万行のプログラムの中身は、フレームワークが自動生成したソースやユニットテストが半分以上占める。
でも、それらのプログラムの整合性を取りながら、一つのWebシステムを曲がりなりにも動かしている事実がある。

以前よりも、大規模なシステム開発が少人数のチームで可能になったのは確かな事実だと思う。

その開発環境を支えているものは何か?
3つあると思う。

【1】フレームワークの威力が上がった

RubyならRails、JavaならS2Sruts/S2daoを使えば、DB層からWebのControler/Viewまで、CoCに従って簡単に書くことができる。
特にDB層は、ルールに従えば、自動生成してくれる。

フレームワークがプログラムの論理的整合性を大部分吸収している。
だから、ルールさえ覚えれば、業務ロジックに専念すればいい。

更に、ユニットテストもフレームワークが提供してくれている。
RailsもSeasarも、ユニットテスト用のディレクトリが既に確保されている。

特にDB層や共通ライブラリは、ユニットテストをプログラミングすれば、最低限の品質は確保できる。
仕様変更があっても、ユニットテストのプログラムがあるから、回帰テストで以前の機能が正しく動いていることも確認できる。

ユニットテストの重要性は、回帰テストでデグレを防止できることだけでなく、JDKやRuby、Tomcat、RDBのバージョンUpのような開発環境そのものが変わっても正しく動くことを保障できる所にあると思う。
システムのハード面のスケールアップにも、ユニットテストが大きな威力を持つ。

【2】無料で使いやすい開発環境の普及

JavaならEclipse、Rubyならemacsやvi、最近ならNetBeansで開発するのが普通だろう。

昔なら、M$のVisualStudio、IBMのVisualAge for Javaのような統合開発環境は高価で、誰もが自由に扱える存在ではなかった。
また、バージョン管理システムも、M$のVSSぐらいしか使い物にならなかった。

でも、JavaではEclipseが2002年以降急激に普及してから、山のようにオープンソースライブラリが増えて、より開発しやすくなった。

バージョン管理システムはSubversion、ビルドツールはAntやMaven、WebアプリケーションサーバーもTomcatやJBossのように、色んなツールが無料で、しかもかなり品質もいい。
ノウハウもネット上にいくらでも転がっている。

一度、開発環境を整えることができれば、新人のプログラマでも、環境の細かな使い勝手を考えずに、プログラミングだけに専念できる。


【3】アジャイルな開発プロセスの普及

Webシステム開発なら、常時ビルド環境はもはや当たり前。
だからこそ、いつでも検証できるし、頻繁なリリースも可能。

テスト駆動開発、リファクタリングというアジャイル開発の基本テクニックも、Eclipseを使ううちに自然に身に付く。
テストを通すようにプログラムを書く帽子、そして、テストが通ったプログラムをリファクタリングで綺麗にする帽子を切り替えることも、数万行近いプログラムを書くうちに、さすがに自然に分かってくる。

また、プロジェクト管理もTracやRedMineのようなWebベースのツールを使うプロジェクトが多くなった。
この部分はまだ洗練されていないと個人的に思うが、少なくとも、カレンダーで開発スケジュールを全員に周知させたり、BTSのようにバグ報告フローを管理するツールはすごく有効。
また、コミットしたソース量を毎晩レポートしてくれるツールがあるおかげで、誰がどれくらい頑張っているか分かる。

今回、数万行も書いている事実は、statSVNのおかげだ。

【今、問われる問題点とは?】

そんな開発スタイルで問われる問題点は、プログラマとしての基本的な技術力だと思う。
例えば、、

・可読性は高いか?
 クラスやメソッド、変数の名前が分かりやすいか?
 きちんとインデントしているか?
 無駄なコメントアウトしたソースがないか?
 JavaDocをきちんと書いているか?

・後から機能追加しやすいように保守性を気にしているか?
 きちんと論理的に分割できているか?
 無駄なフラグは多くないか?
 IF文が3個以上ネストしていないか?
 無駄なローカル変数が多くないか?

・きちんとユニットテストを書いているか?
 カバレッジは100%ですか?
 テストしやすいソースを書いてますか?

などなど。

つまり、保守性や可読性の高いプログラムを意識して書いているか?
一度、本番稼動いているプログラムは、たとえ可読性が悪くとも、たとえユニットテストやリファクタリングの技術があっても、修正するのはすごく難しい。

簡単にプログラムが書けてしまう時代だからこそ、プログラミングの基本スキルそのものが問われているのだと思う。

| | コメント (0) | トラックバック (0)

2008/03/22

【感想】Kanasan.JS prototype.js CodeReading#4

Kanasan.JS prototype.js CodeReading#4へ行ってきた。
今日はわずか13人だけ。
歩く仕様書のnanto_vi先生もおらず、正直物足りない面もあったけれど、ソース解読そのものは結構面白かった。

今日コードリーディングしたprototype.jsのL1652~L2472 は、ブラウザ依存やCSS依存の部分を汎用的に使えるように苦労している所。

IEはバグそのものが多いのか、ラップしたり、苦労している部分が多い。
FireFoxもVer1.8.0のみ特別な処理がある。
Safariは、バグFixしたプログラマが丁寧なのか、コメントしてくれて親切。

それらのソースは、正直綺麗じゃない。
たくさんの人の手が入ったのだろう、コーディングルールが徹底されておらず、インデントや変数名に統一性がない。

okkezさん曰く「バグレポート駆動」なのでしょう、と。
つまり、 バグレポートが上がるたびに、各人が勝手にバグFixして積み重ねたソースなのだ、と。

この状態は、システム開発の結合テスト以降のフェーズに似ている。
仕様書に従ってプログラミングしても、結合テストやシステムテストで、たくさんのバグ修正や仕様変更に伴って、プログラムは本来のあるべき綺麗な構造から少しずつズレていく。
一度、バグ修正したソースへ再び手を入れるのは、誰もが嫌がる。

今日コードリーディングしたprototype.jsも同じように思える。
実際のソースはそんなに綺麗じゃない。
でも、ブラウザやCSSにも依存しないように汎用的なライブラリにしてくれているので、AjaxのようなリッチUIを実装できる。

以前、lapis25さんが、フレームワークの内部のプログラムは、どう書いてもやっぱり汚い部分が残るんですよ、と言っていたのを思い出す。

汎用的で使いやすいライブラリを作るための泥臭いプログラミング。
それも、プログラミングの一側面。

| | コメント (0) | トラックバック (0)

2008/03/18

三項演算子?:の正しい書き方

三項演算子の書き方について、分かりやすい記事があったのでリンクしておく。

三項演算子?:の正しい書き方

Ruby、JavaScriptは、三項演算子を使いまくるソースが多い。
それは、Lispのような関数型言語の発想に似ている。
短絡評価も似たような発想。

条件分岐やループ処理も、DRY原則を徹底して、1行で書き切るやり方。

| | コメント (0) | トラックバック (0)

2008/03/15

【感想】第24回Ruby/Rails勉強会@関西

第24回Ruby/Rails勉強会@関西へ行ってきた感想を書く。

【1】REST思想が解決しようとするもの

moriqさんの講演。
REST思想をアーキテクチャの観点から非常に丁寧に深く解説してくれて、かなり概念が整理された。

Webシステムの特徴のひとつは、デプロイが独立していること。
つまり、クライアントのVerUpは、サーバーは無関係であること。

Railsの弱点は、デプロイにあると思う。
おそらく、JRubyがそれを解決してくれるはず。

REST思想のモチベーションは、セッションを汚さないこと。
できるだけ、画面の状態は、URLが指し示すリソースで持つ。
GET、POSTだけでなく、HTTPメソッドにあるPUT、DELETEを使って、セッションで保持しなくてもいいようにする。

少なくとも、注文ボタンの2度押し問題は、POSTメソッドでなく、PUTメソッドを使えば解決できる。
PUTメソッドは冪等の性質を持つので、1回以上の操作後の結果は全て同じだから。

しかし、ストヤンが指摘したように、RESTで全ての問題が解決するわけではない。
戻るボタン対応は、RESTでは、戻る遷移専用のURLを作る必要がある。
それは面倒で根本的な解決ではない。

戻るボタン対応は、結局、Continuationつまり、継続サーバーを使わないと解決できないと思う。
継続の概念があれば、画面操作がログインチェックで中断されても、スタックに保持した操作で画面を復元できる。
正常処理ならいつでも操作の途中から開始できる。

REST思想と継続サーバーの概念は全く別だ、と帰路の電車でストヤンが力説してくれた。
ストヤンが言うには、TCP/IPプロトコルそのものが限界にあり、SCTPみたいなプロトコルが必要じゃないかと指摘した。

僕はその意見が絶対正しいと思っていない。
REST思想はまだ不十分だけれども、無駄なセッション管理をなくす方向でWebアプリを単純化しようとしている。
Webアプリがステートレスである限り、その方向性は性能も考えると正しいと思っている。

【2】Railsとアジャイル開発

かわばたさんの講演。
Railsで構築したSNSと、現場でのアジャイル開発のお話。

Tagawaさんが、Railsのテスト駆動開発では、フェイクしたモックオブジェクトを使って開発することはないのか?という質問をしていた。

Railsに限らず、最近のシステム開発は、モジュール単位にプログラマをアサインして分業化するやり方ではなく、機能単位でプログラマが担当する。
つまり、1機能に必要なモジュールをプログラマが全て作る。セル生産のイメージに近い。
その意味では、プログラマの責任が大きくなっている。

プログラマはアーキテクトでもある。

【3】FlexとRubyの意外と親しい関係

FlexUG大阪のhirossyさんの講演。
Ruby関西の人は殆ど、Flexを知らなかったらしい。

デモでは、Webカメラで写した画面を触るとポッと反応するアプリをする予定だった。

興味深かったのは、RubyAMF の話。
動画などの情報をAMF3(Action Message Format 3 )という直列化されたバイナリ形式でサーバーとクライアントをやり取りする。
この時、クライアントはFlex、サーバーはRubyで、そのインターフェイスをAMF3であるアーキテクチャ。
この形式ならば、Flexクライアントは、サーバーのAPIをコールするだけで欲しい情報を取得できる。

ストヤンが話すには、FlexはAjaxよりも良い。
理由は、Flexの方がはるかにリッチなUIを作りやすく、更に、動画などのストリーム情報も加工や表示がやりやすいから。

更に帰路の電車でストヤンから、Flexは元々Flashから来たからデザイナーがプログラミングできる。
リッチなクライアントUIはデザイナーに任した方が、いいものが作れるよ、と。

確かに、Ajaxを使った場合、Viewをデザイナーもプログラマも触ることが多い。
だから、デザインをマージする時など、ソース管理がどうしても面倒になる時がある。

個人的には、ユーザ向けWebアプリはAjax、バックエンドの業務アプリはFlexかAirが現在はベストなWebシステムじゃないかと思う。

今回は色んな発表が聞けて楽しかった。


| | コメント (2) | トラックバック (1)

2008/03/11

REST思想とHTTPメソッドの関係

RESTの基本的な発想は、HTTPメソッドでリソースをCRUDできるはずだ、というアイデア。
では、HTTPメソッドは、そもそもどんなものなのか?

安全なメソッドと冪等{idempotent} なメソッド」でいくつか語られている。

「RESTful Webサービス」で「べき等」という概念が出てくる。
「べき等」とは、同じ操作を何度行っても同じ結果であること。つまり副作用がなく安全であることを意味する。

少なくとも、GETはべき等に使うならば、安全であると言える。
しかし、GETで、リソースの削除や更新を行う時も、実はよくある。

REST思想に従うならば、GETは副作用を起こしてはいけない。
POST、PUT、DELETEがリソースの更新で副作用を起こすように使うべき。

RailsはREST思想を忠実に反映している。
また、Strutsも「http://~/***.do」というURLを見ると、RESTの発想を実現しようとしているニュアンスが感じられる。

更に、WebDAVとHTTPメソッドは親近な関係にある。
WebDAV メソッド」ではこんな風に説明している。

WebDAV とは "Web-based Distributed Authoring and Versioning" の略で、Web サーバ上でファイルの編集や管理等の共同作業を行えるようにする事を目的に開発されました。
(snip)
その後、1992 年に書かれた HTTP/1.0 の初期バージョンでは、PUT や DELETE といった HTTP/1.1 で盛り込まれるメソッドに混ざって、CHECKOUT や CHECKIN, SEARCH といった WebDAV で提案されているメソッドも見られます。
これらは明らかに、WWW を「サーバからクライアントへの単なるリソース配布するためのもの」から、「WWW 上でリソース編集を行うためのもの」にする狙いが読み取れます。
この「リソース編集のための仕組みを HTTP に組み込む」という考え方は、PUT や DELETE という形で HTTP/1.1 に盛り込まれ、更に現在の WebDAV へと着実に受け継がれています。

この発想を突き詰めると、「WWW上でリソース編集したいというモチベーションがREST思想なのだ」と言えるのではなかろうか?

| | コメント (2) | トラックバック (1)

2008/03/05

DBはグローバル変数

システムコントロールテーブルに、システムの設定情報、業務の固定情報を載せる。
システムの固有情報を動的に変更したい時があるから。

DBをグローバル変数として持たせる。
Singletonに近い発想。

渡辺さんの本でも似たような話があった。

利点は、プロパティファイルの場合とは違って、アプリケーションサーバーを再起動する必要がないから。
プロパティファイルを変更した場合、アプリケーションサーバーを再起動しなくてはいけない場合がある。

DBがグローバル変数みたいなものなら、システムは関数。

丁度昔のCのプログラムのように、ヘッダファイルにプログラムの状態の値をグローバル変数として持たせた状況に似ている。

| | コメント (0) | トラックバック (0)

2008/02/12

次世代Webフレームワークの設計思想~RESTful Webサービス

「RESTful Webサービス」本を買ってみた。
まだ読んでないけれど、この本を買った動機を振り返ってみる。

【1】Webフレームワークの歴史とその限界

Webアプリは最初はオモチャみたいなものだった。
普通は、掲示板のようなアプリをPerlでCGIを書いて作っていただろう。

そして次第に、ViewからControllerを分離する設計をするようになった。
Javaの場合、JSP+Servletという仕組み。

だが、システムが巨大化していくうちに、Webフレームワークが必要とされるようになってきた。
そのWebフレームワークの基本思想として、MVC2モデルが叫ばれるようになった。
MVC2モデルは、GUIアプリのMVCモデルのWeb版といっていい。

この思想によって、大概のWebフレームワークは、MVC2モデルを標榜するようになった。
そして、Javaはこの思想を突き詰めて、Model部分にEJBを作り出した。

EJBは、永続化装置とネットワーク分散型装置の2つを実装した巨大なビジネスオブジェクト。
EJBはステートフルなBeanとステートレスなBeanの2種類があるが、皆、ステートレスセッションBeanばかり使う。
理由は、ステートフルな方が本当は使いやすいが、ネットワーク越しにステートフルな状態を持つのは遅いから。
確かに最新技術をふんだんに取り入れて魅惑的だが、何しろ重くて実用的にならない。

更に、その頃は、SOAPという概念も出てきた。
SOAPは、Webというネットワーク上でメソッドコールできるようにすること。
つまり、ネットワーク越しのRPC。
でもすごく遅い。
2000年当時は、ネットワーク越しにメソッドコールで1分以上もかかる。
とても使い物にならなかった。

そして、今でもSOAPやEJBは、Webアプリ開発の主流となりえていない。

【2】プログラマにとってステートフル、ユーザにとってステートレスなWebフレームワークとはどんなものか?

Webフレームワークとは大まかに下記の流れと言えるだろう。

HTTPリクエストからデータをもらう

プログラムはそのデータを使ってゴニョゴニョ処理する。
RDBへ放り込んだり、ファイルをアップロードしたり。

プログラムが作ったデータをHTTPレスポンスに渡す

Viewを表示する

画面の状態を保存するには、セッションやクッキーを使うしかない。
クレジットカード番号や個人情報はViewでHiddenで保持するのは危険。

でもセッションの状態管理は難しい。
画面遷移が複雑になるほど、セッションはどんどん汚れていく。

Webアプリの鬼門はいつも「戻るボタン」と「注文ボタンの2度押し」。

例えば、戻るためには、どの画面から飛んできたかを知らないといけない。
前の画面に戻るパターンは、実は、その2個前の画面の状態に依存する例もある。
あるいは、会員登録フローならば、新規会員登録なのか会員情報修正なのかで、戻る場所は違う。
画面遷移を制御するためのフラグをリクエスト変数に追加していくうちに、スパゲティコードになる。

他に、最終注文画面の注文ボタンを2回誤って押したら、同じ商品が2度注文されてしまう。
普通はそんな誤動作を防止するために、注文処理後すぐにセッションをクリアしたり、注文ボタンを押した時刻をHiddenで保持したり、あるいはトランザクション・トークンキーを使ったりする。
どの方法にせよ、たかが2度押し防止のために、かなり面倒な実装をしなければならない。

「境界を越える: 継続とWeb開発、そしてJavaプログラミング」では、そんな疑問に一つの回答を示している。
合言葉は「プログラマーにとってはステートフル、ユーザーにとってはステートレス」。

つまり、画面の状態を保持する機構がプログラマにとって必要。
だが、スケーラビリティやユーザビリティを考えると、ユーザにとってステートレスの方が圧倒的に使いやすい。
この矛盾した設計を最初に実現したのは、実はLispのWebフレームワークだと言う。

Paul Grahamが「ハッカーと画家」の中で、既に1995年のViaWebにおいて、この基礎となっている手法を使ったらしい。
この手法は、『継続(continuation)』というプログラミング制御構造を使うことに意義がある。

この基本的な考え方は、「プログラミング・フレームワークが、アプリケーションの状態をリクエストの前にロードし、また各リクエストの後に保存するようにする」ということ。

GausheというSchemeで作られたKauhaというWebフレームワークでもこの考え方が使われているらしい。

Rubyにも、『継続(continuation)』というライブラリがある。
基本は同じ。
でも、デバッグするとどのステートメントをたどるか分からないのが普通で使いづらいのが普通。
Ruby関西では、yharaさんが講演してくれたのが分かりやすかった。

そこで問題。
『継続(continuation)』を使った場合、画面の状態はどこに保存されるのか?

それは実は、URLに隠れている。HTTPメッセージへ全ての情報(リソース)を渡すのだ。
ここからRESTの話に移る。

【3】RESTの定義とは?そしてRESTを実現したRuby on Rails

WikipediaのRESTの解説が非常に分かりやすい。
HTTPプロトコルについてもう一度おさらいしてみよう。

似たようなプロトコルにFTPがある。
こちらの方がHTTPよりも原始的だが。

FTPでファイルをアップする時、WindowsユーザならFFTPアプリを使うだろうが、ftpコマンドを使って、コマンドラインでもアップできる。
同様に、HTTPプロトコルでも、GETやPOSTコマンドを使って、直接HTTPサーバーに問い合わせることができる。
大まかには、RESTとは、このコマンドを拡張して制限したアイデアを指す。

RESTとは、下記の設計原則を持つと言われている。

◆ステートレスなクライアント/サーバープロトコル
 HTTPメッセージの一つ一つが、そのリクエスト (メッセージ) を理解するために必要な全ての情報を含む。

◆すべての情報 (リソース) に適用できる「よく定義された操作」のセット
 HTTP では操作 (メソッド) の小さな集合で定義されている。
 つまり、"GET"、"POST"、"PUT"、"DELETE"。
 これらはデータ永続化に要求される CRUD の概念に似ている。

◆リソースを一意に識別する「汎用的な構文」
 すべてのリソースは URI (Uniform Resource Identifier) で表される一意的な (ユニークな) アドレスを持つ。
 それは大概、訳の分からないトークンキーかセッションキーのような形式になる。

◆アプリケーションの情報と状態遷移の両方を扱うことができる「ハイパーメディアの使用」
 多くの場合、HTMLかXMLに情報およびその他のリソースへのリンクを含める。
 これによって、リンクを辿るだけで、必要な情報を参照できる。
 状態を逐一保持する必要はない。

これらの設計思想は、SOAPやEJBなどの思想と明らかに異なる。
むしろ、よりシンプルに考えたものだ。

そして、この設計思想を最初に実現したのが、Ruby on Railsだと思う。
少なくともRubyKaigi2006のDHHの講演を読むと、彼がREST実装を強く意識しているのが読み取れる。
更に、最新のRails2.0では、RESTサポートが強化され、セキュリティも改善されていると言う。


Ruby on Railsの凄さは、下記4点に集約されると思う。

・フルスタックなWebフレームワーク
・CoCというシンプルな設計思想
・RJBを使うと、Ajaxと親和性が高い
・RestfulなWebフレームワーク

最後のRestfulという概念は、Ruby on Railsを離れて、もっと抽象化できるはず。
そんな内容が書かれていると思うので「RESTful Webサービス」を読んでみようと思う。

| | コメント (0) | トラックバック (0)

2008/02/06

システムのリプレース案件が最も危険な理由

Joel on Software」を立ち読みして興味深く思えたことを書く。

「あなたが絶対すべきでないこと PART I」という章がある。
Netscapeがブラウザの90%を占めていた頃、何を思ったか、彼らはNetscapeのソースコードを一から書き直すことを決心した。

Netscpapeのアプリをアップデートしていくには、そのソースコードを書き直さねばならない。
文字列を分解してゴニョゴニョした処理をして返すだけの関数が2ページもある!
タコなソースだよ!と。

でも待ってくれ。
このIF文は、IEの古いバージョンのバグに対応するために、ナンシーが書いたものだ。
この処理は、Windows95で動かすために手を入れたもので、ボブが書いたものだ。
つまり、このソースコードは見た目は奇怪でも、きちんと動いているし、過去のバグフィックスも積み重ねられているんだよ。

もし一から書き直したとしよう。
すると、また、これらのバグフィックスを一からやり直す羽目になるんだよ。
何故、IE5.0で動かない?
何故、Windows95で動かない?
何故、MacOS8で動かない?
要らないって? でもお客から苦情が来てるんだよ。

それから3年余り、Ver4.0のまま止まったまま。
ITの世界で3年は途方もない時間だ。
そしてVer5.0をすっ飛ばして、Ver6.0をようやく出した時、Netscapeはシェアを獲得できなかったばかりか、会社そのものも消えた、と。

この逸話には、工業製品レベルのプログラムの品質について、いくつかの示唆を与えている。
一つは、システムやアプリのリプレース案件は非常にリスキーなことだ。

IT業界の業務システム開発は、システムのリプレース案件が非常に多い。
以前はメインフレームでCobolで作っていたシステムを、オブジェクト指向言語でオープン系のシステムで作り変えたい。
VBやAccessで作っていたクラサバのシステムを、Webベースのシステムに作り変えたい、とか。

これらの案件は非常にリスキー。
確かにそれらの技術は古すぎて、スケーラビリティもユーザビリティも耐えられないだろう。
しかし、数年もかけて運用してきたと言う事実はある。
つまり、色んな業務フローに対するバグフィックスや機能追加を重ねて、安定稼動したシステムになったのだ。

それらを捨ててスクラッチで作り直す時、過去のノウハウも全て捨ててしまうことと同じ。
お客さんから見れば、既に動いているシステムがあるのだから、仕様ははっきりしているでしょう、と思うだろうが、肝心のシステムは中身が全く違う。
運用していくうちに、バグフィックスや機能追加で、恐竜のように馬鹿でかくなった中身は、最新のオブジェクト指向言語で、同じようにたくさんのバグフィックスを重ねて積み上げたものに変わる。
同じソースコードの断片は一つもないはず。

リプレースする最新の技術力をコントロールできるか、そして、仕様を完全に設計しきれるか、が問われる。
普通は、どのプロジェクトもデスマーチになると思う。

もう一つは、プログラムの保守性や移植性、再利用性が、どの時代になっても、言語がいくら発展しても難しいこと。

言語が違えば、そのライブラリを再利用するのは難しい。

とはいえ、最近は、JavaからCのソースをコールしたり、RubyからJavaやC#のソースをコールすることもできるようだが。

特に再利用性は、そのライブラリの粒度に大きく依存する。
再利用できる程度は、フレームワーク程度ぐらいで、昔から夢想するビジネスオブジェクトレベルまでなかなか辿り着けない。

IT業界で仕事してきて、同じような失敗を何度も繰り返しているような気がするのは、上記の現象が解決されないからだろう。
システムのリプレース案件ほどリスキーな仕事はない。

追伸

この本の著者Joelさんは、来週のデブサミに来日されるとのこと。
ちょっと楽しみですヽ(^o^)丿

| | コメント (0) | トラックバック (0)

2008/01/13

【再考】プロセスで品質を作りこむ

「コードコンプリート」第2版下巻を輪読した。
品質、テスト、デバッグの章を読んで、非常に参考になることばかりだった。

「コードコンプリート」を読むまで「プロセスで品質を作りこむ」という格言の意味が分からなかった。

整理するために感想を書いてみる。

【1】テスト自体はソフトウェア自体の品質を改善しない

「コードコンプリート」によると、テスト(単体・結合・システムテスト)をいくらやっても、一般に存在するエラーの高々50%しか検出されない。

テストの結果は品質の指標になるだけだ。
ソフトウェアの品質を上げたいなら、テストを増やすのではなく、開発プロセスを改善しなければならない、と。
その実例や測定結果も載せていた。

この指摘には衝撃を受けた。

どのプロジェクトでも、テストケースを増やしたら、ソフトウェア品質が上がっているように思えないだろうか?
それは、痩せるために体重計にのる回数を増やしているだけ。
痩せないのなら、新しい体重計を買うのではなく、ダイエット方法を見直さなければならない。

つまり、開発プロセスそのものを見直さなければ、品質は上がらない。

【2】ソフトウェア品質の原則~品質を改善すると開発コストは下がる

「コードコンプリート」によると、欠陥を検出したり修正するコストは後工程になるほどコストが高くなる。
エラーやバグが紛れ込んだ時期が早ければ早いほど、そして、ソフトウェアのほかのパーツに紛れ込んで見えなくなるほど、それを排除するコストは高くなる。

これをソフトウェア品質の原則と称して、色んな実例を載せている。

いわく、欠陥の低いプロジェクトは開発工数が短い。エラー排除はソフトウェア作業で最も高価で時間がかかる。

いわく、要求や設計の変更が原因でも、デバッグやテストが原因でも、コーディングのやり直しにかかる時間を減らすことが生産性と品質を上げる最善策だ。

いわく、品質の低いソフトウェアを開発して修正するよりも、品質の高いソフトウェアを開発する方が安価だ、と。

いわく、開発の早いPGは最も多く速く欠陥を検出し、修正した、と。

「コードコンプリート」には「悪魔のささやき」というブラックジョークがある。

・欠陥は憶測で探せ
・問題を理解しようとして時間を浪費するな
・真っ先に思いついた方法で解決せよ

この手法を意外に実行していないだろうか?

特に、プロジェクトリーダーは、納期を遵守するために、本来あるべきプロセスを省いてしまう時が多々ある。
その影響は、品質劣化という結果に直結する。

プロジェクト終盤でプロジェクトリーダーがよくやるパターンは、リリースする機能の数を減らして、限られた範囲の機能の品質を保持することに注力すること。

つまり、7つの品質特性のうち、信頼性を重視するために、スコープを狭くして作業工数を減らす方向へ持っていくことをよくネゴする。
そして、開発・検証プロセスはできるだけ省略しない。

但し、この手法が使えるには相当の政治力が必要。
スコープを狭くするとは、システムのあるべき機能を削るのだから、お客様の本来の業務の一部をシステムがサポートしないことを意味する。
信頼性を削ることと同じ。

この手法を「プロジェクトを成功させる 現場リーダーの「技術」 」では「ウルトラC的アクション」と言っている。
つまり、ゴールの前提条件を変えてしまうこと。
ゴールはお客様との合意の上にあるわけだから、お客様の要求を根本的に変更させるぐらいの相当の政治力を必要とする。

【3】品質改善のために、テストだけでなくソースインスペクション、ペアプロも組み合わせる

「コードコンプリート」では、テストだけでなく、ソースインスペクションなど他の手法も組み合わせることを推奨している。
特に、「コードコンプリート」によると、ソースインスペクションの効果を強調している。
「コードコンプリート」が説明するソースインスペクション方法はとても組織的だ。

モデラー、作成者、レビューアの3人が、設計書やチェックリストから、あくまでもソースの欠陥を検出することへ注力する。
そして欠陥を修正し、その結果を確認する。

ソースインスペクションを重視する理由は、そのプロセスが自ら最適化される仕組みがあるからだ、と「コードコンプリート」著者は言う。
つまり、標準的なチェックリストと標準的な役割によって体系化されるし、フィードバックを繰り返す過程でチェックリストが改善されるし、インスペクションの準備や修正の速さや効果度が監視されるので最適化される、と。

この表現は、CMMIのレベル3の標準的プロセスをイメージさせる。

つまり、インスペクションプロセスは、体系的(レベル3)で、繰り返し実行することが可能(レベル2)で、測定結果(レベル4)に基づいたフィードバックを使って自身を改善する(レベル5)。

このテクニックは他のプロセスにも応用できるし、「コードコンプリート」では「開発組織に当てはめたら、これらの考え方は組織に最高水準の品質と生産性をもたらすだろう」と言っている。

逆に、「コードコンプリート」ではウォークスルーは批判的だ。
効果が低いという測定結果も載せている。

「コードコンプリート」が否定的な観点を提示するのは、ソースインスペクションという焦点が曖昧で、公式なインスペクションに組織やメンバーが否定的な所ほどウォークスルーを使っているという経験談があるからだろう。

また、「コードコンプリート」では、「テストファーストプログラミングは過去10年間に登場したソフトウェアプラクティスの中で最も効果的なものの一つ」と言い切っている。

「コードコンプリート」では、XPを新しい分野の欠陥排除テクニックと呼び、その測定結果から、かなり効果的であると断じている。
実際、XPのプラクティスでは、ペアプロによるソースインスペクション、テスト駆動開発によるテスト重視、デイリービルドで回帰テストなど、意図的に複数のプロセスを組み合わせているからだ。

その意味では、XPを含めたアジャイル開発は、過去10年のソフトウェアの歴史で工学的に、あるいは経験で裏打ちされたプラクティスなのだ、とも言える。


「コードコンプリート」は上下2巻で1000ページ、1万円を越える大著だが、この本2冊で、プログラミング技術だけでなくソフトウェア工学の知識も殆どカバーする。
すごい本だと思う。

↓上巻はこちら


| | コメント (0) | トラックバック (0)

2007/12/24

JudeからRoRのWebアプリを作る

気になった記事をリンクしておく。

Judeのクラス図からActiveScaffoldのコードを自動生成する

うしおさんの記事で、興味深いのは、「こういう風に作ろうかな」と曖昧に書いたクラス図から、Webアプリが簡単に作れること。
RoRとActiveScaffoldのおかげで、かなり楽に作れる。

| | コメント (0) | トラックバック (0)

2007/12/19

Javaで関数型言語みたいに書く

Javaで関数型言語のcase式みたいに書く」記事を見ると、Javaでも、IF文やSwitch文を値を持たせられる。
その記事に載っていたソースは下記の通り。

class CaseExpPpoku {
public static void main(String[] args) {
char nengou = args[0].charAt(0);
System.out.println(
nengou == 'H' ? "平成":
nengou == 'S' ? "昭和":
nengou == 'T' ? "大正":
nengou == 'M' ? "明治":
"??");
}
}

すげぇ。。

kanasan.jsでも、JavaScriptのprototype.js を皆で読んでいた時、三項演算子を3個も繋いで処理を行うソースがあった。

三項演算子は使わない方がいい、と言われていたが、このソースを見ると、三項演算子はLispのS式みたいなもの。
オブジェクト指向という思想とは違う発想。

オブジェクト指向も既に15年以上も使われて、いい加減、賞味期限が来ている。
次の新技術は、関数型言語なのかもしれない。

| | コメント (0) | トラックバック (0)

2007/12/08

JavaScriptは関数型言語だ

今日、11時過ぎにkanasan.js#2に行ってみた。
既に20人以上も会場にいて、プレゼンが始まっていた。
なんと朝9時から夜9時まで、12時間のマラソン勉強会(^。^)

最初は、前回の復習。
講演者の話す内容は非常に面白かった。
継承、MixIn、wrap、いずれの具体例も非常に興味深い。

それから、Prototype.js1.6.0のコードリーディング。
12時間かけて、1000行を読んで、ようやくAjaxオブジェクトの所まで解読しましたよ!

JavaScriptは面白いなと思った箇所がある。
Prototype.jsの内部で、Hashを作っているソースがある。
そのソースに、intersect() という関数があり、その定義は、Lispみたいなソース。
つまり、無名関数をつなげまくって、わずか2行のソースで、二つのリストの共通部分を取り出す。


intersect: function(array) {
return this.uniq().findAll(function(item) {
return array.detect(function(value) { return item === value });
});
},


Rubyで言えば、上記の関数は、ブロックを2個使っているのと同じ。
最近のJavaScriptは無名関数を多用することで、エレガントに書こうとしているように見える。
これってLispに似てないか?

JavaScript読書会でも議論になったが、無名関数を使った場合、変数のスコープがJavaの場合と微妙に異なる。
レキシカルスコープ、ダイナミカルスコープの話もあった。

Haskellにあるcurry化のような関数(curry)を定義していたり、実装内容は、関数型言語の影響を強く受けているように思える。

関数型言語っぽい使い方をする利点は、変数が1回しか代入できないことよりも、無名関数やクロージャを使って、関数をまるで変数のように使い回すところにあるように思う。

そして、イベントの発火のようなロジックを手続き型言語よりもエレガントに書ける部分にあるように思う。

だから、Ajaxのようなイベント処理でビックリするような使い方ができるのかなと思ったりする。

今までJavaScriptは使えない言語と思っていたが、「JavaScriptは関数型言語である」という認識で、今後も注目していくつもり。

| | コメント (1) | トラックバック (0)

2007/11/23

【JavaScript】Kanasan.JSの資料

関西.js(通称:kanasan.js)で以前開かれた時、JavaScriptのオブジェクトやプロトタイプチェーンについて、主催者kanasanが非常に分かりやすく説明してくれた。
その時の講演資料が公開されているので、メモしておく。

Kanasan.JSの資料

JavaScriptを使って分からなくなるのは、Core JavaScriptと、ブラウザ独自のオブジェクトを混乱して使っているからかな。

| | コメント (0) | トラックバック (0)

JavaScript第5版読書会#1

JavaScript第5版読書会#1へ行ってきた。
大阪で平日の夜なのに、18時半には30人以上も集まっていたよ(驚)
読書会の内容は、JavaScriptの辞書である通称「サイ本」を最初から読むこと。

3時間の議論はすごく中身が濃かった。
その時の感想をメモ。

【1】JavaScriptは、他の言語と文法が微妙に違う所を認識していないのが、バグの温床になる

変数、メソッド、オブジェクト、配列、ハッシュなど、最初から読むが、僕には退屈。
20章「HTTPによる制御」にあるAjaxを早く読みたかった。

でも、主催者のkanasanから、Ajaxでバグにはまる原因はJavaScriptの文法をきちんと理解していないからですよ、と言われた。

確かに、JavaScriptのブロックは、CやJavaと異なる。
つまり、IF文などの制御構造で定義したローカル変数は、グローバル変数に近い。

また、暗黙の型変換をすごく多用する。
よくあるパターンは、変数に「!!」を使うと論理型へ型変換する。
prototype.jsでも「!!」は良く出てくる。

【2】JavaScriptのオブジェクトは、インスタンスそのもの
  ~nullでなくundefinedがある理由

JavaScriptのオブジェクトは、ハッシュに近い。
つまり、image.width と image["width"] は同じ。
これによって、プロパティを動的にいじることが出来る。

また、オブジェクトのプロパティにfunctionを設定できる。
つまり、データと関数は同じ意味を持つ。
Ajaxでも、HTTPリクエストのプロパティへ手続きを設定する仕組みを使う。
例えば、GMailのように、ブラウザをリフレッシュせずに非同期でサーバーから最新メール情報を取得する。

JavaScriptのオブジェクトは、コンストラクタをあまり意味がない。
何故なら、必ずインスタンスがあるから。

thisオブジェクトは神様みたいなオブジェクト。
ブラウザ上では必ずオブジェクトはあるみたい。

JavaScriptでは、JavaのNullPoniterExceptionに当たるエラーとして、undefinedが良く出る。
これは、該当するインスタンスが見つからないと言う意味。

また、JavaScriptの継承は、プロトタイプチェーンと呼ぶ。
JavaやC++、Rubyの継承とは異なる。
この辺りも面白い。

【3】最近のWeb開発のトレンドがサーバーサイドからリッチUIクライアントへ移行しつつある

Ajaxが出現するまで、JavaScriptは使えない言語だった。
メモリリークは良く出るし、ブラウザ依存だし、使い勝手が悪かった。
でも、Web開発のトレンドがサーバーサイドからリッチUIクライアントへ移行しつつある今、JavaScriptは重要な意味を持つ。

Googleがやり始めたことは、リッチUIクライアントを操作する言語としてJavaScriptを使い、サーバーサイドからUIクライアントのJavaScriptソースコードを自動生成する仕組みを導入したこと。

Google Web Toolkitも発想は同じ。
Railsにある、RJSも全く同じ。

この発想は、JavaやRubyが、JavaScriptという他言語を生成するという、いわゆるメタプログラミング。

でも、サーバーサイドがクライアントよりも主導権を握るという従来のWeb開発スタイルは踏襲している。
この流れならば、リッチUIクライアントであろうとも、サーバーサイドから制御できるだろう。

Web開発のトレンドは今、JavaScriptが表舞台にいるのかもしれない。

【番外編】
JavaScript 第5版」によく出てくるリファレンス本は下記になる。
持っておくと便利かも。

| | コメント (2) | トラックバック (1)

2007/11/18

NetBeansがRuby開発環境に向いている

NetBeansでRailsの開発が出来ると聞いて、さっそくダウンロードしてみた。

DBさえ設定すれば、Railsのディレクトリやソースを自動生成してくれる。
使い勝手はすごくいい。

一番欲しかった機能は「コード補完」。

defを書けば勝手にendが補完される。
メソッドを書いている途中で、メソッド名を補完してくれる。

メソッド名にフォーカスを当てると、JavaDocのように、機能内容がポップアップされる。
#いわゆるJavaのメソッドにマウスポインタを合わせたときに表示される吹き出し(ホバー表示)のこと。

参照元のクラスやメソッドにも飛んでくれる。

プログラミングはEmacsやviだけで十分かもしれないが、大規模開発になると、自分たちが作ったライブラリを参照しながら書くのが普通なので、コード補完やホバー表示は重要。

更に、JRubyも入っているので、色々使えそう。

NetBeansも、EclipseやVisualStudioのような機能が揃いつつある印象を受けた。


過去のSmalltalkは、VisualAgeという統合開発環境と共に育った。
Javaも、VisualAge for JavaやEclipseという統合開発環境が出て、爆発的に普及した。

だが、Javaを作り出したSunよりも、Eclipseという統合開発環境とWebSphereというアプリケーションサーバーを持つIBMがJavaマーケットで一番儲けた。

今度は、SunがRubyをサポートして、同じような事象を狙おうとしている。

RubyもNetBeansという統合開発環境で普及するだろうか?

| | コメント (0) | トラックバック (0)

2007/11/04

Mavenで開発ライフサイクルを制御する

Mavenを使う時があり、「Apache Maven 2.0入門 Java・オープンソース・ビルドツール 」を参考にした。

Mavenを実際に使ってみて、概念や経験を整理してみる。

【1】Mavenとはビルドツールの標準テンプレートである

 MavenはJavaのビルドツールである。
 Antも同様だが、Mavenの特徴は汎用ビルドツールのテンプレート版みたいなもの。

 Mavenには下記の主要な概念、仕組みがある。

1-1.アーティファクト

 Mavenによって作られるプロジェクトの成果物を指す。
 一般には、JAR、WAR、EARファイルなどのコンポーネント。
 他に、JavaDoc、JUnitテストレポート、DJUnitレポート(カバレッジのレポート)も含まれる。
 
1-2.POM(Project Object Model)

 ビルドするための情報(メタデータの構造)が定義されたファイルのこと。
 普通は、pom.xmlというファイル名で作られる。
 Mavenは、pom.xmlに書かれた依存ファイル、成果物の定義を参照して、リリース用モジュールをビルドする。
 Antのbuild.xmlに相当する重要なファイル。
 
 この中で重要なタグ情報や仕組みは、下記である。

1-2-1.artifactID
 成果物のファイル名を指す。

1-2-2.groupID
 アーティファクトを作成した組織のID。
 Javaで言うパッケージ空間に相当する。

1-2-3.dependency
 アーティファクトを作るために必要な依存ライブラリを定義する。
 普通は、WebフレームワークのJARファイルやJacartaCommonライブラリが定義される。

1-2-4.version
 アーティファクト(ビルドしたモジュールや依存ライブラリ等)のバージョンを指す。
 グループID、アーティファクトID、バージョンによって、モジュールやライブラリは一意に識別され、かつ作られる。
 ビルド時は、このバージョンが最も重要な意味を持つ。

1-3.依存関係の解決
 Mavenは、依存ライブラリのグループID、URL、バージョンを指定しておくと、ネット上からダウンロードして関連付けてくれる。
 他に、開発時に共有ライブラリを自作して、依存関係を定義することも出来る。
 この仕組みのおかげで「マルチプロジェクト」という概念も実現される。

 Mavenは最終的に、「artifactId-version-拡張子」(例:app-1.0.1.jar)という形のリリースモジュールを作るために存在すると言い切ってよい。
 
【2】Mavenは、ソフトウェア・ファクトリー・ツールである

 IBMの記事「EclipseでMavenを生かす」にMavenの特徴が非常に洗練されて紹介されている。

Mavenは、末端ながらソフトウェア・ファクトリー・ツール・ファミリーに属するものです

ソフトウェア・ファクトリーは、次の3つの概念を中心に構成されています。

1・スキーマ。
 アプリケーションを構成する様々な成果物の構造と、それらの相互動作を記述するメタデータを提供します。
2・1つ以上のテンプレート。
 スターター・キットと、アプリケーション構築に必要なもの全てを提供します。
3・拡張可能開発環境(extensible development environment)。
 コンポーネントの設定、カスタム化、組み立てに使われます。

Mavenの基本的な目標というのは、ビルド・プロセスを標準化することであり、またCBTD(code-build-test-deploy)のサイクルに品質と再現性をもたらすことです

 上記の通り、開発ライフサイクルとは、下記の流れになる。
 Mavenは、ビルド~リリースの作業を自動化してくれる。

1.コーディング

2.ビルド

3.テスト

4.デプロイ(リリース)

 ソフトウェアファクトリーはM$が提唱している概念の一つ。
 不勉強なのでソフトウェアファクトリーを完全に理解していないけれど、Mavenがやろうとしていることは、ソフトウェア製造工場の作業の理想形なのだろう。

【3】Maven以前のビルドプロセスを振り返ってみる

 ソフトウェアの歴史は、プログラミングだけでなくビルドの歴史でもある。
 古くはアセンブラからC、C++に至るまで、ビルド作業は最も重要な作業の一つ。
 リリースしてシステムを動かすために必須だから、プログラミングよりもはるかに大事かもしれない。
 
 Javaの歴史もビルド作業の変遷という視点から眺めることが出来る。
 
3-1.僕が初めてJavaプログラムを書いた時、サーバーへJSPやpropertiesのようなテキストファイル、Classのようなバイナリファイルを、手作業でディレクトリに配置していた。
 当然、Classファイルは100個以上にのぼることもあり、リリース作業手順書を詳細に作る必要があった。

 他には、JSPは初めて実行すると初めてコンパイルされるため、表示に時間がかかる状況があり、わざわざJSPだけをリコンパイルするツールも数年前まであった。

 また、リリース後には必ずWebSphereやWebLogic、Tomcatを再起動しなくてはならない。
 つまり、リリース作業が10分間と言えどもシステムが止まってしまう。
 その間、お客の業務は止まるのだから、限られた時間でしかリリースできない。
 そのためにアナウンスが必要だったり、非常に手間がかかる。
 だから、リリース作業には細心の注意が必要だった。

3-2.じきに、JARファイルやWARファイルでソースを固めて、手作業でアップロードするようになった。

 この利点は、アプリケーションサーバーを再起動した時に、勝手にデプロイ(配置)してくれること。
 でも、以前デプロイしたモジュールに上書きされない時があるので、手作業で以前のデプロイモジュールを削除することをしていた。
 
3-3.それから、Antを使ってビルドするようになった。
 build.xmlにビルドに必要な作業情報を全て書き込めば、勝手にコンパイルしてくれる。
 しかも、「ant clean」のコマンドを使えば、過去にコンパイルしたモジュールも削除して、リコンパイルできる。
 classファイルを手作業でアップロードしていた頃に比べると雲泥の差があった。
 
 でも、Webシステムが大規模化して依存ライブラリが増えるに従い、バージョン管理が非常に難しくなってきた。
 古いライブラリをバージョンアップしたいのに、一度動かしたシステムの依存ライブラリをバージョンアップして動作しなくなったらどうするのか?
 また、色々な環境(開発テスト環境、受入テスト環境、本番環境)ごとにbuild.xmlを作り、ソースコードを管理するのはまだまだ手作業の部分が多く、危険が多い。

【4】Mavenによるバージョン管理で「要件から仕様化するプロセス」を制御する

 Mavenは、ビルド作業のテンプレートとも言える。
 ビルド作業の決まりごとを守れば、設定を極力減らすことができる。
 ビルド作業でも、「Convention over Configulation」という概念が出てくる!

 とりわけ僕がMavenを使ってみて最も威力があると感じたことは、「バージョン管理」。
 
 オープンソースのアプリケーションに「開発(リリース)履歴」があるけれど、その内容を強力に管理できる。
 
 管理者の視点から見ると、バージョンと機能を1対1に紐づけることが可能になる。
 つまり、pom.xmlにリリースする機能ごとにバージョンを付けることで、デグレを防げるだけでなく、新規開発と運用保守のモジュールを平行して開発するのが以前よりもはるかに容易になった。
 
 仕様さえ固められれば、「この新しい機能をいつリリースするのか?」の場合はバージョンを1個増やした新規バージョン、「このバグはどのバージョンで直すか?」の場合はマイナーバージョンアップで管理すればいい。
 いつでも以前のバージョンに戻すことが出来る。

【5】Mavenは開発プロセスのフレームワーク(テンプレート)になりうるか?

 Mavenによるバージョン管理で初めて、CMMに出てくる構成管理や要件管理をイメージできたように思う。
 仕様さえ固めれば、ビルドしたモジュールを機能単位に制御できる。

 また、実際にMavenを使うと、JAR(WAR)というコンポーネントが単なる物理ファイルだけでなく、人や作業を含む1プロジェクトの成果物の概念まで昇華される印象を持った。
 というのも、開発者と成果物は1対1にマッピングできるから(N対1、1対Nもあるが)。

 自分が作ったモジュールにバージョンを付けるという意味は、自分がその成果物の最終責任を負うことを意味する。
 つまり、「何を修正したのか」という機能内容がバージョンに含まれていて、そのコンポーネントの品質と仕様、他コンポーネントへの依存関係も、その人が全て把握していることになる。
 その意味では、pom.xmlにバージョンを付ける事ができる人は、非常に大きな権限と責任を持つことになる。

 このようにして、コンポーネントと開発者がリンクされることで、コンポーネントの依存関係に従って、UMLの配置図がプロジェクト組織の依存関係とマッピングできる。
 つまり、共有ライブラリよりも画面に近いサブシステムの方が多くの依存関係を持つ。
 共有ライブラリのバージョンが上がると、画面に近いサブシステムもバージョンアップせざるを得なくなること。

 Mavenを使うと、自社の開発プロセスを標準化できる可能性がある。
 
 とはいえ、Mavenを使いこなせたレベルとは言えず、以前よりも開発がスムーズになったわけでもない。
 でも、Mavenを使って、以前のプロジェクトと大きく異なると感じたことは二つ。
 
 一つは、以前よりももっと大規模なシステム(モジュール)を作れるようになったこと。
 もう一つは、開発プロセスのボトルネックが、プログラミング工程ではなく、要件から仕様へ落とす設計やプロジェクト管理の工程に移ってきたこと。
 
 M$では、開発者やテスト担当者よりもビルド担当者の方が大きな権限を持つと聞いた。
 Mavenによるビルド作業はまだ研究の余地があるように思う。

| | コメント (0) | トラックバック (0)

2007/11/03

【JavaScript】Kanasan.JSに行ってきた

土曜の午後にKanasan.JS(関西.js)へ行ってきた。
コミュニティの趣旨は「皆でprototype.jsのソースコードを解読しよう!」というもの。
Kanasan.JS」でしか告知していないのに、25人も集まった(衝撃!)
どうやら殆どの人はTwitterを通じて知ったらしい。

わざわざこのコミュニティのために東京(!)からはるばる来た人もいたよ!

約3000行のうち300行しか解読できなかったけれど、奥深い議論が出来て楽しかった。
楽しかった感想を徒然に残す。

【1】プロトタイプチェーン~クラスとインスタンスの区別はない

 JavaScriptのオブジェクト指向は、Java等とは異なり、プロトタイプベースと呼ばれる。
 継承の概念がOOとプロトタイプでは大きく異なる。
 その仕組みをプロトタイプチェーンと言われるらしい。
 
 OOでは、型を継承する。
 プロトタイプは、型を継承せず、親クラスのインスタンスを内部に持つ。
 つまり、プロトタイプオブジェクト配下のメンバーは、プロパティみたいなもので、他のプロパティをコピーして作られる。

 コンストラクタは、OOのコンストラクタではないため、すごく使いにくい。
 だから、initilizeを使う。
 JavaScriptのインスタンス生成はRubyのinitializeに近い。
 
 皆の議論を聞くと、Javaで知っているオブジェクト指向と微妙に異なる点が面白かった。

【2】prototype.jsはRuby on Railsの影響を強く受けている

 参加者から「ProtoTypeは、Railsの影響を強く受けている」という話を聞いて驚いた。
 Railsの開発者がPrototypeの開発チームにも入っているらしい。

 実際、prototype.jsには、文字列のライブラリを再定義しているのだが、そこに出てくるgsubなどは、Rubyのライブラリに非常に近い。
 特にArrayはそうですよ、と。

 Ruby on Railsは、JavaやPerl、PHPなどのWebフレームワークに大きな影響を与えているが、まさかJavaScriptまで影響を及ぼしているとは思ってもみなかった。

【3】最近のWeb系の技術はJavaScriptが熱い

 僕が今回の催しに興味を持った理由は、最近のWeb系システムでは業務ロジックよりも、Ajaxを使ったUIプログラミングの方が要求されるスキルが高いから。
 今、技術革新がサーバーサイドのJavaからフロントエンドのJavaScriptへ移りつつある気がする。
 更に、prototype.js、jquery.jsは、Railsの影響を受けているのも興味を引く。

 恐るべしRails。

 主催者のkanasanは非常の物腰の柔らかい方で、人望が集まりそうな人。
 次回もやりましょう、と声が上がった。
 
 関西でもJavaScriptが熱くなるかな??

| | コメント (0) | トラックバック (0)

2007/08/15

ソフトウェア開発は野球よりもサッカーに似ている

 ソフトウェア開発は、野球よりもサッカーに似ている。
 そう思わないか?

 野球は、徹底的な役割分担のスポーツ。
 ピッチャーは投げるだけ。バッターは、長距離砲、俊足で打率を稼ぐ人。
 あるいは、キャッチャーやショートのように守備専門の人。
 監督は、選手を駒のように使ってやりくりする。
 
 逆にサッカーは、個人の能力にかなり依存した組織スポーツ。
 1対1のシチュエーションが結構多い。
 
 日本のサッカーは組織力重視。
  外人に体格で負けるから、パスサッカーでできるだけ個人勝負を避ける。
  いつまで経っても個人で勝負できない。
  だから、個人の能力に一番依存するシュート力が弱い。

 ソフトウェア開発を連想してみよう。

 役割分担による組織力も大事だが、個人のスキルに大きく依存する。
 その人しか開発できない、その人しか仕様を知らない、のように、役割と人が密結合の状況がすごく多い。
 だから、その人が休んだり、出張でいなくなると、チームのスピードが止まる。

 プログラマは自己主張が強い。
 というか、人が書いたプログラムは、その人の経験、思想が織り込まれた成果物だから。
 それゆえに、その人の設計思想が優れていたり、自分の肌に合うものならば問題はない。
 でも、普通は、他人の思想なんてすぐに理解できるわけではないし、自分の感性にそぐわない時が多い。
 
 こんなタコなプログラムよりも、自分が書いたプログラムの方がはるかにいいぜ、と、プログラマは皆思っているのではないだろうか?
 
 だからこそ、プログラムは個人技。
 だからこそ、ソフトウェア開発はサッカーに似ている。

| | コメント (0) | トラックバック (0)

2007/06/15

【Perl関西】Perlベストプラクティス~プログラミング作法は何故必要か?

 昨夜、kansai.pmのPerlベストプラクティス勉強会#2(略してPBP)に参加してきた。
 勉強会の内容は、エクストリームリーディング方式で「Perlベストプラクティス」を読む読書会。
 るびま勉強会と違って、物静かだが、コアな議論ができた。

【1】Perltidyrc~Perlベストプラクティスに従ったPerlプログラムのCheckStyle

 コーディング流派の多いPerlは、どうしても、ソースの可読性が低くなりがち。
 例えば、Perlの場合、$変数がスカラー変数なのか、参照変数なのか、が分からなくなる時がある。
 だから、変数名に「ref_」「_ref」を付けるやり方があるらしい。

 話を聞いたら、Perlベストプラクティスの本がPerlのプログラミング作法らしい。

 そのためのチェックツール「Perltidyrc」があるらしく、それを使うと、Perlベストプラクティスの本の何頁と相違しているから警告メッセージが出た、ということができるらしい。
 但し、英語の本らしいけれど。
 すごすぎ~。

【2】何故、プログラミング作法は必要なのか?~JavaでもRubyでもPerlでも同じ

 インデントや変数名のネーミングルール、1ステートメントの改行などの細かなルールがPerlベストプラクティスにある。
 何故そこまでこだわるのか?
 
 答えは、プログラムの可読性を高めたいから。
 その理由は、運用保守フェーズで、プログラムの可読性が保守性と密接に関わっているから。
 
 だが、ラフにプログラムを書きたい時がある。
 パッと思いついたアイデアを書き込んで動かしてみたい時、コーディングルールや整合性にあまりこだわらずにサクッと書きたい時がある。
 そして、実際に動かしながら、書いたプログラムのロジックの整合性を突き詰めながら、自分のアイデアを確かめていく。
 そんな時に、パッと思いついたプログラムは、上級者になるほど読みやすい構造になっている時が多い。

 いのうえさんが「7年経ってようやく長い変数名が自然に出てくるようになりました」と言っていたのが印象的だった。
 プログラムを書く手が自然にプログラミング作法に則っているのが上級者。
 スパゲティのようなプログラム、手が全く動かず空白の多いプログラムが多いのが初心者。

 個人的には、モデリング作業がプログラミングと同じ感覚で、簡単に動作確認できて、モデルの整合性をチェックできるようになれたらいいのに、と思う。

| | コメント (0) | トラックバック (0)

2007/06/08

Eclipseリファクタリング・メモ

 Eclipseの使い方を一覧で分かりやすく説明しているHPがあったので、メモ。
 特にリファクタリングの手順が分かりやすい。

Eclipseリファクタリング

 Eclipseのリファクタリングは非常に使いやすいのに、何故か皆、使ってない。
 ファウラーのリファクタリング本を読んでないのだろうか?
 Javaプログラマにとって、綺麗なプログラムを書くための技術が全て詰まっている良書なのに。

【リファクタリングの目的】

 最近、ソースインスペクションをする立場になってみて、仕様を理解せずに長々と書いている下品なプログラムを見ると、すぐにカチンと来てしまう(-_-;)

 Fatなメソッド、Fatなクラスは、不吉な匂いがする。
 女性と(だけじゃなくて男性も)同じく、太ったクラスはダイエットすべき。
 
 リファクタリングする真の目的は、誰でも理解できるプログラムにして保守性を高めることにある。
 特に、プログラマは派遣契約が多いため、書き散らしたプログラムは3ヵ月後には作者不明のソースになってしまい、下手なソースは誰も修正できなくなる。
 そうならないように、誰でもプログラムの意図をすぐに理解できて保守性を高めることは、運用保守フェーズで大きな影響を持つ。

【リファクタリングすべき箇所】
 ペアプロしながら、下記の点に注意してリファクタリングする時が多い。

■スペルミスや分かりにくいメソッド名や変数名
 → すぐに「名前変更」 (皆、英語は弱い(-_-;))

■一塊の機能を見つけたら → 「メソッド抽出」
 → 他クラスへ「移動」することが多い

■意味不明な定数を見つけたら
 → 「定数の抽出」

■無駄に長いgetter処理、ループ処理で何度も使われるローカル変数
 → 「ローカル変数の抽出」
 → ここから、メソッドの抽出をやって、引数の依存関係を減らす

■クラス内で何度も使われて、状態として保持した方が良い変数
 → 「フィールドのカプセル化 」

■ローカル変数をプログラムへ戻す
 → 「インライン化 」

■メソッド名の引数が、intやStringのようなプリミティブな型ばかりでやたらと長い
 → 引数の中で関係あるものをクラスとして抽出し、「メソッドシグニチャの変更」で引数を減らす

■継承構造を作りたい
 → 「インターフェイスの抽出」
 → インターフェイス、抽象クラスを作り、具象サブクラスを作る

■2つのサブクラスに似たような処理があって共通化したい時
 → 「プルアップ」
■プルアップの逆操作
 → 「プッシュダウン」

 プルアップって皆知らないみたい。
 機能を共通化したい時の手法は、下記2種類しかない。

○サブルーチン呼び出し(いわゆるファンクションコール)
○継承を使って親クラスに共通ルーチンを持たせる(いわゆる実装継承)

 オブジェクト指向に慣れていない人は、継承構造を使うプログラミングが苦手みたい。

 以前、るびま勉強会でRubyistと継承関係について議論したら、Rubyistは継承を殆ど使わず、特異メソッドやMixinで代用するらしい。
 Javaプログラマとしては、上記2種類を意識して使い分けることが多いから、ちょっと違和感あり。

■サブクラスを動的に使い分けて生成したい
 → 「ファクトリーの導入」

 サブクラスを使って処理を使い分けている時、必ずIF文、case文がある。
 その部分をファクトリーメソッドで置き換えて、外から来るフラグに応じて、生成する具象クラスを切り替える。

 オブジェクト指向に慣れていない人は、インターフェイスだけで書かれたプログラムが今どんなロジックを通過しているのか、を理解できない時が多い。
 だから、デバッグしても、今どのインスタンスで実行されているのか、という観点が無い。

【番外編~Rubyの場合は??】

 Rubyでも最近いい本「Rubyist Magazine出張版正しいRubyコードの―RubyistのRubyistによる、Rubyistとそうでない人のための」が出た。
 るびま勉強会(関西)でも読んでます。


 
 Rubyistによると「ファウラーの本よりも初心者向けだがいい本ですよ」とのこと。
 中身を読んでみると、Rubyのリファクタリング版という感触だった。

 Java屋さんとRuby屋さんにとって、こういうリファクタリング本は、プログラミング技術を上げてくれる良書。
 もう一度読み直してみようと思う。

| | コメント (0) | トラックバック (0)

2007/06/02

Erlang勉強会#1

Erlang勉強会#1へ行ってきた。
その時のメモ。

【1】Erlangとは?

 ErlangのWikipediaには次の説明がある。

Erlang(アーラン) は、コンピュータにおいて汎用的な用途に使うことができる並列処理指向のプログラミング言語および実行環境である。 Erlangの直列処理のサブセットの言語は、関数型言語であり、先行評価を行い、変数への代入は1回限りであり、動的型付けである。 Erlangはエリクソン社により次の条件のシステムを構築できるよう設計された。

分散化された環境
障害に耐性をもつ (フォルトトレラント)
ある程度のリアルタイム性を備える
無停止で稼働する

 最近、静かに流行している言語。

【2】開発環境のインストールとサンプルソース実行

 ここのBlogに詳しい。
 「Erlang (BEAM) emulator」を起動できれば成功。
 Rubyのirbに似ている。

 参考書は、英語の本がある。
 そこから、日本語のベータ版がPDFで落とせるらしい。

 その日本語のPDFの内容が素晴らしい!
 関数型言語、論理型言語の意味がようやく分かったような気がする。 

 サンプルソースとして「ピタゴラス数を計算する」を実行してみた。

-module(pythag).
-export([pythag/1]).

%% ピタゴラス数を計算する

pythag(N) ->
[{A,B,C} ||
A <- lists:seq(1,N),
B <- lists:seq(1,N),
C <- lists:seq(1,N),
A+B+C =< N,
A A*A+B*B =:= C*C
].

 実行ログは下記の通り。

c(pythag).
pythag:pythag(16).

[{3,4,5}]

 ソースを見て分かるように、「何がしたいか?」を書くだけで「どのように書くか?」は気にしない。

【3】「=」は代入演算子ではなく、パターンマッチング(評価する)

 関数型言語では、単一代入変数という言葉が良く出る。
 つまり、変数は1回しか代入できない。

 そして、「=」は代入演算子ではなく、パターンマッチング。
 この点が、CやJavaなどの手続き型言語に慣れた僕たちを戸惑わせる。

 つまり、LHS=RHSとは、「右辺値を評価して、その結果を左辺値のパターンにマッチさせる」。
 これは、評価しているのと同じ。
 実際に実行してみる。

X=(2+4).
X=6.
→正常

X=10.
→エラー

Y=6.
X=Y.
→正常

 「=」は評価しているということ。
 Xへ1回目に代入する時は、必ず真。
 2回目に代入する時は、値が同じ場合のみ、成功する。

 この事実は、変数Xがプログラミング言語の変数ではなく、数学で使う変数に似ている。
 つまり、X=X+1が使えない!!

 パターンマッチングの概念は、関数型言語だけでなく、Perlにも出てくる。
 この発想があるからこそ、正規表現が使える。

 色んな言語を知ることは、「現実をモデル化する技術」を一つ増やしてくれる。
 それが楽しい。

| | コメント (0) | トラックバック (0)

2007/05/13

【Rails関西】軽量の人は繊細な人を兼ねる~JavaからRubyへ

 今日のRails関西に行ってきた。
 artonさんという大物有名人の講演も聞けて、ワクワクする勉強会だった。
 その感想を書いてみる。

【1】Javaはクールな言語だった

 artonさんは「Javaも好きです」と言っていた。
 Javaは元々こんな特徴があって、10年前はクールな言語と言われていた。
 つまり、Javaはインターネットを意識した初めてのプログラミング言語だった。

・仮想マシン(JVM)の上で動く
・バイトコードで読める
・ガベージコレクションがある
・移動コード(セキュリティ機構)を持つ
 つまり、リモートホストからローカルホストへ転送され実行される機構を持つ

【2】Javaは現代のCobol~業務アプリは繊細な作り

 でも、実際の現場では、Javaで業務アプリを作っても、やっぱり業務アプリは壊れやすい。
 そして、広範囲に膨大に使われて、Javaが全てを解決したとはとても言えない現状がある。
 最近は、軽量の言語の方がいいのでは、という傾向もある。

・業務アプリケーションに最も使われている
・型があるから安全でしょう(本当?)
・コンパイルするからバグが見つかる(本当?)
・Eclipseという統合開発環境があるから初心者でも簡単
・オブジェクト指向言語だが、今時そうでないプログラミング言語を見つけるのが難しい
・private、interfaceなどの言語仕様があるけれど、今はどの言語でも持っている

【3】それでもJavaには利点がある

 にもかかわらず、Javaにはうまい仕掛けがある。
 これらをうまく使えば、何かできないか?

・Reflection
・Annotation
・Bytecode Modification
・Java Native Interface

【4】軽量の人は繊細な人を兼ねる~軽量なRubyが繊細な業務アプリへ進出してきた

 「軽量の人は繊細な人を兼ねる」という言葉をartonさんから初めて聞き、心揺り動かされた。
 つまり、「軽量なRubyが繊細な業務アプリへ進出してきた」ということ。

 実際、一部のSIerが、WebアプリをJavaからRubyへシフトしつつある。
 このあたりの事情は、倉貫さん(XPユーザーグループ代表)のBlog『JavaからRubyへ―マネージャのための実践移行ガイド』でも取り上げられている。
 この傾向の意味は、RubyがITビジネスとして使えるという安心感を示している。

【5】だからRjb(Ruby Java Bridge)

 そこで、RubyからJavaライブラリを再利用するするために、Rjb(Ruby Java Bridge)を作ったとの事。
 Javaのライブラリはそこら中に転がっているのだから、そのライブラリを再利用すればいいじゃないか、と。
 この発想は、PerlのPluggerをRubyからコールして再利用しようという以前の講演のモチベーションと全く同じ。
 
 その仕掛けの詳細はサンプルデモなどを読んでもらえればいいが、講演では、スレッドやスタック回りの開発部分の話がすごく面白かったけれど、時間切れで、もう少し聞きたかった。

【6】時代はJavaからRubyへ?(.NETじゃないよ)

 artonさんは、何もRailsじゃなくてもASP.NETだって同じようにすぐに出来るよ、とサンプルデモを講演してくれた。
 色んな言語での比較は面白い。
 
 僕の少ない業界経験では、M$系のツール(Visual Studio)をフルに使いこなす技術者の生産性はJavaよりも高い。

 にも関わらず、やっぱりJavaは面白い。
 理由は、.NET系は自動生成したソースコードを解析するのはブラックボックスを触るような感覚で非常に難しいが、Javaなら自分で最初から組まないと動かないので、機構がすごく良く分かる。
 同じように、RubyOnRailsも、ソースを最初から最後まで追いかけられるので、機構がすごく良く分かる。

 元々、オブジェクト指向という発想はネットワークと相性がいい。
 サーバーはオブジェクトに似ている。
 だからインターネットを意識した言語、あるいはインターネットのキラーアプリが時代を変えるのだろうと思う。
 
 そんな講演を聞きながら、そして一部のSIerがRubyで実際にシステム構築していく事例を見聞きすると、今と言う時代の技術が変化しつつあるのを感じる。

| | コメント (0) | トラックバック (0)

2007/03/20

プログラミングは「ブロックを組み合わせる」感覚に似ている

 若い開発者に僕が書いた設計書を説明後、プログラムをJSPから書き始めるのか、それともServletから書き始めるのか、聞いてきた。
 僕は、まずJSPを動かしてからServletを書いたら、と言ったら、コンパイルエラーばかりで全く進まない。
 僕の意図は、JSPServletを確実に動かしながら、fakeした機能を一つずつ実装していけばいいだろ、ということだった。
 結局、若い開発者にValueObjectからボトムアップで書かせたら、コンパイルエラーもなくなり、ようやく書けた。

 プログラムを書く時、トップダウンから始めるか、それとも、ボトムアップから始めるか?
 PGやSEなら一度は、はまった経験があると思う。

【1】プログラミングとは、機能を組み合わせていくこと

 IT業界に入った時、先輩から、「プログラマは数学者とは違った能力を要求される。機能を組み立てる感覚が大事だ」と言われた事がある。

 プログラミングとは、小さな部品(モジュール)を別の部品からコールして、メインプログラムを作っていくこと。
 その時に、データ構造とかアルゴリズムなどの数学的知識はあった方が良いが、それよりも、機能を実現するために、数多くのモジュールを組み合わせて整合性を合わせるのが大事。

 Perl関西で知り合ったプログラマが「Perlの面白さはCPANモジュールを組み合わせる所にあるんです」と言っていたのが印象的だった。

 これはまさにボトムアップからのプログラミングの感覚。

【2】テスト駆動ツールがあれば、トップダウンのプログラミングは可能

 ボトムアップのプログラミングで怖いのは、作った小さなモジュールが正しく動かないまま、メインプログラムを実装して動かないこと。

 でも、JUnitなどのテスト駆動ツールを使えば、モジュールが小さいほどテストしやすく、品質も良くなる。
 逆にテスト駆動ツールがあるならば、トップダウンでインターフェイスを定めながら、仕様が不明な機能はfakeしながら実装できる。

 ボトムアップのプログラミングの弱点は、細部にこだわりすぎて、実現する機能をインターフェイスとして考えられなくなること。
 テスト駆動ツールを使えば、その弱点を補うことが出来る。

【3】設計者はトップダウンで要求を仕様化していく

 設計者の仕事は、あやふやな要求を仕様として落としていくことにある。
 つまり、要求から大まかな機能を洗い出し、その整合性を取りながら、機能を矛盾なく実現できるレベルまで細分化していく。

 設計者の頭の中では、機能をInputとOutputのペアで考え、ひたすらそのペアの連鎖で全ての機能が矛盾なく動くか、ロジックを組み立てる。
 つまり、どう実現するかというHowよりも、何を実現するかというWhatを重視している。

 そして設計手法は、自然にオブジェクト指向設計になる。
 機能をオブジェクトに見立てて、メッセージを送ったら、自分が何をするか知っているから期待した結果を返す。
 そのオブジェクトを整合性を保持したまま協調動作できるか?という考えをずっと突き進めるだけ。
 これは、トップダウンで仕様を煮詰めていき、最終的にインターフェイスを決めるまで突き進めることと同じ。

 オブジェクト指向設計の良い所は、メッセージ送信という発想によってInputとOutputの関係だけに注力できることと、実現できるかどうかというHowの部分をカプセル化して設計を先に進めることができること。

 トップダウン設計では、要求から仕様へ落とし、最終的にはクラス図へ落とす。その時点で、ほぼ設計は出来上がる。
 クラス図ができれば、実装は単なる機械的作業にすぎない。

【4】WhyとWhatとHowの関係

 Howを考えるのは、実装であり、プログラマのお仕事。
 Whatを考えるのは、仕様であり、SEのお仕事。

 Whatを洗い出す時、要求の理由や背景を考えた方が良い時がある。
 つまり、何故そんな機能が必要なのか、をぶつけていくと、そもそもそんな機能は必要ではなかったとか、実は別の本質的な機能が必要だった、ということもありうる。

 要件定義とは、Whatで考えるために、Whyをどれだけお客から引き出せるか、という技術を要求しているのだろう。

【5】プログラミングの楽しさはモジュールの組み立てにある

 プログラミングの楽しさは、少年時代に積み木やブロックで好きなように組み立てた経験に似ている。
 そして、その組み立てた物は、実はすごく脆い。
 ほんの少しバランスが崩れただけで、全部壊れてしまう時だってある。
 その辺りのハラハラドキドキ感が楽しいのかもしれない。

 デスマーチではハラハラドキドキしたくないけどね(^^)

| | コメント (2) | トラックバック (0)

2006/06/11

【感想】Kansai.pm 第1回Perl翻訳フェスタ

Kansai.pm 第1回Perl翻訳フェスタへ行ってきた。
このイベントは、Perl愛好者がPerlライブラリなどの英語ドキュメントを翻訳して公開しようという企画。
10人ほど集まって和気あいあいの雰囲気で、前回の勉強会と違って面白かった。

【1】翻訳支援ツール OmegaT で翻訳してみる

 翻訳は、Diffやバージョン管理が面倒なため、支援ツール OmegaTで翻訳してみることになった。
 文節ごとに区切られた前回の翻訳文章を覚えてファジー翻訳など、コード補完の様な機能が付いていたり、結構面白い。
 でも、作成途中のベータ版らしく、スペルチェック、バージョン管理などの機能はまだまだ。

 慣れている人は、8時間で400字詰め原稿用紙10~20枚翻訳していくらしい。僕は全然でした。。

※参考:OmegaTのYahooGroup

 オープンソースライブラリの翻訳活動は、完全にボランティア。
 バージョンアップに追いつけず、やる気がなくなると、ドキュメントはすぐに古くなるらしい。
 また、個人のHPに翻訳ドキュメントを置いていると消失してしまう危険性があるから、なるべくライブラリ本体のHPへUploadしてほしいとのことでした。
 色んな気遣いや注意があるようだ。

【2】SkypeでOmegaT作成者Jean-Christophe Helaryから説明を受ける

 皆初めて使うツールなので、作成者からじきじきにレクチャを受けた。
 Skypeは仕事でも使う時はあるけど、こういう場面で自然に使えるんだよなあ。
 音声だけなのですが、内臓マイクを通して会話して、プロジェクターに映った画面を見ながら操作するのは、見てて面白かった。

【3】Haskell のレクチャを受ける

 昼食後の休憩時間に、まだ世に出ていないPerl6のインタプリタはHaskellで作られているらしいという雑談から、Haskell のデモを見せてもらった。
 Haskell を見るのは初めてですが、「 0 + "hello"」をエラーとしてしまう強い型チェック、モデルの証明のような論理を構成して検証するのがやりやすいという特徴などの話を聞いた。
 Javaでようやく導入されたGenericsも、Haskell には元々付属している機能だと言う。
 色んなデータ型を作りやすいから、Perl6のインタプリタ機構も作れたんですよ、と言う。

 オブジェクト倶楽部でも連載が始まったけど、密かなブームなのだろうか??

 Perl関西は他のコミュニティと違って、ノートPCがMac、Linux使いの人が多かったり、オープンソースの活動に詳しい人も多く、技術的に面白い。

| | コメント (0) | トラックバック (0)

2006/04/10

プログラミング言語を成分解析したら

はしもとさんのBlogで、巷で噂の成分解析をプログラミング言語で解析した結果を読んで笑った。

perlの83%は宇宙の意思で出来ています

Rubyの99%はむなしさで出来ています

phpの72%は勢いで出来ています

Javaの52%は犠牲で出来ています

JavaScriptの68%は覚悟で出来ています

 調子に乗って、C#を成分解析してみたら。。

C#の71%は毒電波で出来ています
C#の10%は気の迷いで出来ています
C#の9%はミスリルで出来ています
C#の7%はお菓子で出来ています
C#の3%は成功の鍵で出来ています

 毒電波って何だろう?

| | コメント (0) | トラックバック (0)

2006/03/19

Perl関西はハッカーのコミュニティ

 日曜の昼下がりに京都で開かれたPerl関西に行ってきた。
 今日の京都は、雨から小雪交じりになって寒すぎ(m_m)
 にも関わらず、30人も参加者がいて、勉強会も懇親会も盛り上がった。

【1】Perl屋さんはハッカーが多い

 講演者のプレゼンのノートPCを見ると、殆どの人が、MacかLinux上で、Emacsを普通に使いこなしている。
 しかも、Perlを使いこなすだけでなく、RubyやLispを使いこなす人も多い。
 HaskelやMLにも興味を持って話す人もいた。

 彼らの話を聞くと、CよりもJavaの方が1万回のループ処理が速い時もあるんですよ、とか、プログラミング言語のライブラリの中身は、ライブラリを使う人が簡単に使えるようにするために、結局汚い事が多い、等、プログラミング言語の特徴をよく押さえているという印象を持った。

【2】Perlはプログラミング言語として「緩い」特徴がある

 Perlの標語にこんな言葉がある。

 There's More Than One Way to Do It 

 他にもいろんな方法があるよ

 普通に書ける処理を別にこんな風にも書ける、というパターンがPerlには多い。
 いわゆるシンタックス・シュガーを使うと、いくらでも短く書ける。
 なみかわさんの講演では、「頭を柔らかくして、良い刺激を受けて元気になろう(^^)」という話があった。

 でも、この特長には功罪があり、他の人が読めないソースになってしまって保守できないという弱点もある。

 また、Perl関西の他の講演者も話していたが、「プログラミング言語としてPerlは緩い」所がある。
 変数や関数の隠蔽が無頓着だったり、オブジェクト指向の導入が他の言語に比べると....だったり。

 やはりPerlは、正規表現、ファイル操作、CGI、Wikiなど、お手軽に作り上げる所に最大の長所がある。
 すぐに建てて、用が足せば捨ててしまう。

 PerlやRubyなどに触っていると、プログラムは設計そのもの。
 アイデアをすぐにプログラムに起こしてみて、実際にすぐに動かせる所に最大の特徴がある。

【3】開発のスピードとプログラミング言語の関係
 最後に、Webシステムから業務システムへ開発が代わった人と話していた時、業務システムの開発はスピードが遅いんですよ、と聞いたことが気になった。

 PHPやPerlによるWebシステムの開発の場合、3ヶ月ぐらいのスパンでリリースするから、スピードが非常に速い。開発スタイルも、リリース後、お客さんの要望を取り入れながら改善していくことが多い。
 しかし、業務システムの場合、プロジェクトの期間そのものがもっと長いことが多い。
 だから、ずっと忙しい感じで、スピード感がないんですよ、と言っていた。

 とまあ、JavaやC#のようなガチガチの静的型付け言語に慣れている身にとって、刺激になった。

| | コメント (0) | トラックバック (0)

2006/03/14

C#のdelegateをTemplateMethodの代わりに使う

 とある勉強会でC#2.0の新機能を議論する機会があった。
 「匿名メソッド」「イテレータ」について説明を聞いたが、いずれもDelegate、コールバックに関わる。

 イテレータはRubyで言うならば、ブロックそのもの。
例: array.sort{|a, b| b<=>a}

 Perlにも、ハッシュのソートで似たような構文がある。
 Cのクイックソート関数 qsort も比較関数をコールバックに使っている。

 匿名メソッドは、無名Delegateと言ってよい。
 Javaなら、Threadを使ってインナークラスを実装する時とかに似ている。

 C#のDelegateはEventで使うサンプルしか知らないので、自分はまだ理解し切れていないのだが、Delegateの他の例を教えてもらった。
 彼によると、DBコネクションの管理に使ってみる、とのこと。
 つまり、DBコネクションをオープンしてクローズするルーチン処理を行うメソッドの引数に、デレゲートを置き、そのデレゲート内部でSQL発行の処理を行う。
 これってまさにTemplateMethodそのもの。
 こんな使い方があったとは!
 
 C#がJavaと大きく違う所は、Delegateにある。
 Javaならインターフェイスでベタに書かざるを得ない所が、C#ならすっきり書けるが、慣れないと可読性が落ちる。
 コールバックという概念は奥が深い。

| | コメント (0) | トラックバック (0)

2006/03/12

Ruby関西が今熱い!~Ruby is Agile!

昨日、Ruby関西に行ってきた。
50人の部屋が満員御礼になるほど盛況で、今、関西で一番熱いコミュニティではなかろうか?

サブタイトル「Ruby is Agile!」は、XPJUG関西の同僚が紹介した言葉です(^^)

感想は以下の通り。

【1】女子大生が書いたソースをコードレビュー
かずひこさんのレッスンで、女子大生が半年前に書いたソースのコードレビューがあった。
20行ほどのプログラムは、放物線の軌道を数値計算する内容で、ループ処理、コメント、変数名に修正が施された。
しかし、それだけにはとどまらず、会場の質問者からの突込みが熱かった(^^)

Q. 変数名をv1, dtではなく、velocity、nextTimeみたいに分かりやすくして欲しい。
小波先生: コメントと連動させれば問題ないでしょう。

#コメント無しでも読めるようにプログラムを書くために必要では?
#保守のたびに、ソースだけでなくコメントまで修正する2度手間がかかりますよ。

Q. For文を使うのではなく、イテレータやブロックを使うなど、Rubyらしいプログラムを書かないのか?
かずひこさん:この程度のプログラムでやるのは大人気ないと思いまして、やりませんでした。

#会場は思わず爆笑(^^)

懇親会では、小波先生が「(会場から質問があるたびに)まるでわが子(娘)を切り刻まれるようで胸が痛かった」と言っていたが、プログラムはそんなに悪くなかったと思う。

【2】C、Perl、PHP、.NET、Javaをやっている人がRubyに興味のシグナルを送っている

懇親会で自己紹介を聞いたら、C、Perl、PHP、.NET、Javaなど、開発者が多種多様。
Rubyって、Java開発者はRubyOnRailsに衝撃を受けて興味を持つが、他の開発者はオブジェクト指向のスクリプト言語として興味を持つらしい。
Rubyは殆ど知らないけれど、オブジェクト指向でスクリプトをやるならRubyだろう、という動機が多かった。

【3】コミュニティで学生を育てる

懇親会でスタッフに聞いたら、参加者50人のうち20人は学生。どうりで若い人が多いわけだ。

最も印象に残ったのは、40代の部長の肩書きを持っているスタッフが、勉強会で一番楽しい時間は、かずひこさんの初級者レッスンで、TA(Teaching Assistant)として若い人にRubyの質問に答えることだ、と言っていた事。

小波先生、かずひこさん、更には他の講演者やスタッフ皆が中心となり、学生を育てようという雰囲気がある。
こういう発想や雰囲気を持つコミュニティはあまりないので、大事にして欲しいと思う。


| | コメント (0) | トラックバック (1)

2006/03/04

使い捨てのプログラム

 システム開発において、設計・製造・テスト・保守フェーズで一時的なプログラムが必要になる時が多い。

例えば、、

・画面項目から、大まかなDB定義書を作り出す。
・仕様書からプログラムのテンプレートを吐き出す。
・テスト仕様書からJUnitのテンプレートを吐き出す。
・JUnitからテスト仕様書を生成する。
・テストデータ、DB仕様書からSQL文を生成する。
・既存システムにあるソースから、調査時に必要な情報をGrepする。
・既存プログラムからCRUDしているテーブルとソースの対応表を作る

などなど。
結構、力仕事でカバーしていませんか?

【何故、使い捨てのプログラムが必要か?】

システム開発の現場では、結構、頭を使わないルーチンの力仕事は多い。
Javaを使ったWebシステムであろうと、結局、Javaを書いているよりも、PerlやVBAを使う方が多い時もある。

特に、仕様書を作る時や、設計時に既存プログラムを調査して仕様を決める時に、使い捨てのプログラムによって作業を速く正確に行えるかどうかは、設計の品質そのものに響く。
一時的に使うだけだが、作業効率を上げるために大変重要。

これらのプログラムは、使い捨てのプログラム。
プログラムそのものも、インターフェイスをきちんと考えて作る必要はなく、とにかく速く作ることが最優先。
だから、きちんと書く必要はない。

【プログラミング言語は何を選ぶか?】

Excelの仕様書を自由自在にいじるために、結局、VBAが必要になる。
基本は、マクロで基本操作をなぞった後、プログラムをカスタマイズすることが多い。

テキスト処理には、色々あるが、やっぱりPerlが一番簡単。
Windowsなら、ActivePerlかCygwinを入れればいいだけ。
Perlなら、Cライクに書けるし、あんまり深く考える必要がない。

今なら、Rubyを選択する人が多いかな?
WinOLEでExcelも扱えるし、正規表現も使えるし。

でも、Rubyで書いた時、Perlよりも短く書けない。
たかがGrepや一括置換したいだけなのに、たいそうなプログラムを書かざるを得ない。
まだRubyに慣れていないせいもあろうが。。

【プログラミング言語は2種類ある】

言語には、型チェックが厳しい重量級プログラミング言語と型チェックが甘い軽量言語(Light Weight Language)の2種類があるように思う。

前者は今なら、Java、C#、Cとか。
後者は、VBA、Perl、Rubyとか。

型チェックが厳しいプログラミング言語は、品質最優先の業務システムが向いている。
開発スタイルもドキュメント志向で、重量級プロセスになりがち。

型チェックが甘い軽量言語は、速く作ることが最優先のWebサイトが向いている。
更には、テキスト処理などの定型的なルーチン作業で威力を発揮する。

この2つのプログラミングの感覚は大きく異なる。

重量級言語は、プログラムを育てていく感覚。正確さ、丁寧さが大事な感覚がある。
設計では、「疎結合」「コンポーネント志向」を重視するから、リファクタリングなどで品質を保持することが優先される。

軽量言語は、使い捨てのプログラムを早く作る感覚。正確さよりも、早く作る方が大事な感覚がある。
 「3年で陳腐化するWebサイトの構築には軽量言語のほうが向いている」記事では、逆に「密結合」「非コンポーネント志向」が良しとされるようだ。
重量級言語と視線も動機も正反対な所が面白い。

どちらが良いというよりも、向き不向きがあるだけ。

【使い捨てのプログラムを書く能力の重要度は高い】

システム開発の現場にいると、大抵の優れたプログラマはツール作りが上手い。
ルーチン作業を自動化するために、使い捨て感覚でプログラムをすぐに作ってしまう。
後で、そのツールが重要になってきて、後でメンテナンスするようになる時も多い。

使い捨て感覚で作っているからメンテナンスしにくいのかと思ったら、優秀なプログラマだけあって、実は読みやすく再利用しやすい時が多かった。

Javaなどのオブジェクト志向言語をマスターするのも重要だが、使い捨てのプログラムを書けるだけのプログラミング能力も重要ではなかろうか?

【最近の傾向】
RubyOnRails などを見ると、Webシステム開発そのものも使い捨てを念頭に置いて開発する必要性が多くなったのではないか。

知り合いのアジャイラーが、プログラムが使い捨てで良しとされるのは感覚が違う、アジャイルと同様にプログラムを育てていく感覚が大事なのに、と言ったことが気になる。

システムをスクラップ・アンド・ビルドで開発しても良しとされるケースが増えてきているのかもしれない。
特に、Webシステムはスピードが速すぎるから。

| | コメント (0) | トラックバック (0)

2006/03/02

軽量言語とビジネスの関係

 「3年で陳腐化するWebサイトの構築には軽量言語のほうが向いている」記事を読んで、開発スタイルとビジネスには密接な関係があることを改めて感じさせられた。

 くらぬきさんの話「EnterpriseXP」でもあったが、XPが使えるビジネスには、サービスを早くリリースしてビジネスを展開するタイプと、金融系のようにきっちりと業務を決めてシステム開発を進めるタイプの2種類がある。
 前者は、軽量言語が向いていて、後者はJavaのような強い型付け言語が向いているのだろう。
 前者のビジネスモデルは、はてなやMIXI等が思いつく。軽量言語としては、Perl、PHP、Rubyがあるのだろう。

 上記の記事で注目すべき点は、システムの受注のスタイルが異なることだ。
 普通は、「ユーザー企業の情報システム部門がシステムを発注し、大手システム・インテグレータ(SIer)が受注する」という形になる。
 ところが、「ユーザー企業の営業部門や広報部門がシステムを発注し,大手広告会社が受注する」という形が多いという。
 となると、顧客サイドは技術に疎いため、技術面だけでなく、システムを開発するプロセスそのものでも顧客をコントロールできる力がより一層重要になる。
 おそらく顧客は、Webデザインの延長でしか考えていないだろうから。
 だから、普通のSIerよりも敷居が高いかもしれない。

 軽量言語は、言語だけでなく、ビジネスそのもの軽く動きやすい方が特徴が出やすいように思える。

| | コメント (0) | トラックバック (0)

2006/02/24

dJUnitでカバレッジテスト

 自分が書いたプログラムをdJUnitでカバレッジのテストをするのが楽しい。

 カバレッジを目で見ることができることそのものが楽しい。

 情報処理試験で、分岐網羅やテストについて概念や用語を習うけれど、実際に理解して使いこなせている人はどれだけいるのだろうか?
 カバレッジのテストが重要なのは、プログラムの品質そのものに直結するから。

 JUnitのテストプログラムを書くのは簡単で、むしろテストケースを洗い出す方が難しい。
 テスト仕様書にあるテストケースで全てのステップを通過しているか、更には全ての分岐を通過しているか、を頭の中だけでイメージするのは、ステップ数が多くなるほど漏れが起きやすい。

 dJUnitを使うと、JUnitのテストメソッドを実行後、テストで通過していない行にマーカーが付く。
 少なくとも、マーカーを全て消すようにテストメソッドを実装していく。その作業は結構楽しい。

 テストプログラムが先にありきの本来のテスト駆動のやり方ではないけれど、今のやり方は、既に作られたプログラムが存在し、そのプログラムの分岐を全て網羅するようにテストメソッドを実装していく。
 設計力がしっかりしている人は、最小個数のテストケースで全ての分岐を網羅できるが、漏れがないことを証明するのは結構難しい。
 少なくとも、dJUnitのように網羅した箇所をレポートで自動生成できるなら、かなり手間は省ける。

 Eclipseが出現して4年以上経つけれど、色んなツールが出ていて、開発環境が以前と比較にならないほど整ってきている。
 特にテスト系ツールは、プログラムの品質に直結するから、最重要だ。

 しかし、Java+Eclipseに比べると、他の言語の開発環境は使いづらい。。
 Rubyも何とかしてくれないかな。

| | コメント (1) | トラックバック (1)

2006/02/18

デザインパターン再考

 各人でバイブルと呼んでもいいぐらい影響を受けた本、そして愛用している本はあると思うが、自分にはGoFの「オブジェクト指向における再利用のためのデザインパターン」が相当するように思う。

 仕事で手が空いている時は、この本のCD-ROMに付属していた抜粋HTMLをよく読んでいるからだろう。

 デザインパターンとは、「より良いインターフェイス設計手法」と呼ぶことも出来る。
 23個のパターンは、粒度の違いはあれど、いずれも珠玉の概念だ。
 
 そもそもデザインパターンに惹かれるのは何故だろう?
 それは、似たようなインターフェイス設計を何度も行った経験があるから。
 詳細設計やプログラミングでデジャブをいつも感じるから。
 リファクタリングと絡めると理解しやすい。

 23個のデザインパターンは、個人的には「ポリモルフィズム」「仲介コントローラ」「インスタンス管理」の3種類で分類できると考える。

1.殆どのパターンはポリモルフィズムの原理を使っている。

 ポリモルフィズムの意義は条件分岐の除去だ。
 実際には、複雑なIF文を呼び出し側から呼ぶ側へ移動することにある。この手法を徹底すると、複雑な条件分岐のアルゴリズムがModelからViewへ移るため、最終的にはリフレクションで条件分岐を全て除去できる。

 具体的には、ポリモルフィズムの対象オブジェクトは、アルゴリズム(Strategy)、状態(State)、要求(Commnad)、再帰(Composite)、コンテナ(Iterator)、文法処理(Interpreter)によって観点が異なるだけ。

 2個のパターンを組み合わせたパターンもある。
 DecoratorはCompositeとStrategyを組み合わせたパターンだし、Chain of ResponsibilityはDecoratorにイベントの概念を追加したパターンと言える。

 特異なパターンがVisitorだ。
 以前は「Visitorパターンはどこで使うのだろう?」と疑問に思っていたが、一言で言えば「マトリックス型のポリモルフィズム」。
 つまり、Visitorクラスはswitch文をクラス化したものとして、その構造が自然に現れる。

2.仲介コントローラを導入するパターンは、複雑な処理を委譲する原理を使う。
 仲介コントローラを導入する意義は、処理の複雑さを凝集度の観点から、一つへまとめたり2個以上へ分割することだ。

 仲介コントローラの対象オブジェクトの役割が、インターフェイス適合(Adapter)、処理の仲介(Proxy)、Controllerの共通インターフェイス(Facade)、オブジェクト間の複雑な通信制御を一つにまとめるもの(Mediator)などと観点が異なる。
 
 最も奥が深いのは、Observerパターンだ。Observerパターンはイベントの概念そのものだが、Multicastパターンで実装されることが多い。
 JavaとC#ではプログラミングスタイルが大きく異なる部分でもある。

3.インスタンス管理を導入するパターンは、用途によって異なる。

 ポリモルフィズムと組み合わせ(AbstractFactory)、コンストラクタ置換(FactoryMethod)、唯一のインスタンス生成(Singleton)、インスタンス複製(Prototype)、インスタンスの履歴保持(Memento)などがある。

 デザインパターンは、実装言語によって大きく異なる部分がある。
 Java、C#、VB、Rubyなどで書いてみると、実装言語の制約でデザインパターンを使えない時があったり、デザインパターンそのものの実装が長くなったりする。
 実装言語の比較によって、自分なりのデザインパターンの解釈を今後、連載してみたいと思う。

| | コメント (0) | トラックバック (0)

2006/01/29

Ruby関西とiPod

 昨日、Ruby関西の勉強会に出てきました。


 「IE+iPod」「DRUM(ドラム)」「Ruby/TkORCA」「かずひこさんの初級者レッスン~継承と委譲」を聞いてきましたが、初級者向けで聞きやすかった。


 毎回、素敵な講演を用意して下さる講演者、会場準備担当者の方に心から感謝します。


 


 iPodにはまっている自分にとって、「IE+iPod」が一番興味深かった。


 Yahooの株式情報を自動検索させるとか、iTunesの曲からGoogleイメージ検索でジャケット画像を探して貼り付けるとか、使い方によっては色々と出来そう。Rubyのソースを見ましたが、Unixのシェルスクリプトみたいでそんなに難しそうには見えなかった。


 テキストファイルをWindows付属の音声認識で読み上げた音声ファイルをiPodで聞くサンプルは一番印象に残った。この使い方ができれば、通勤電車や歩いている時間を丸ごと勉強時間に当てることが出来る。朝の通勤ラッシュ時間は無駄な時間になりがちだから。


 cuzic さんは丁度勉強されているという中小企業診断士のテキストを音声ファイルにしていましたが、聞いてみたらお経のようで、慣れないと聞き取れないのは笑いました。


 Windows付属の音声認識コントロールパネル付属のSumは声質が悪い(^^) 音声ファイルはVectorでも買えるそうで、女性の声が一番聞きやすかった(^^)


 速聴は、脳内活性にいいそうです。でも、お経は勘弁だなあ(^^)


  iTunesのクラスライブラリをRDoc形式で初めて見ましたが、講演者のcuzic さんが話したように、すごく綺麗な構造をしている。



 ライブラリ、アルバム、アーティスト等のクラスは、iTunesの表示メニューそのものに対応していて、メソッドもこんなものかな、とすぐに連想できる。
 COMって僕には印象が悪いのだが、iTunesの場合は勉強してみる価値があるかも。


 iPodの普及で、大量の音声データを持ち運べる環境が整ったことで、Apple自身も予想しなかった使い方が生まれている、という記事を新聞でも読んだ。


 落語をPodcastで無料配信して落語のマーケットを増やそうとする試みや、大学で生徒全員にiPodを配って英語リスニングに使ったり、予備校で簿記や資格試験の授業を音声ファイルで配ったりする例があった。単に音楽を聴くだけでなく、授業や勉強に使ったりもできる。


 テキストの音声読み上げは色んな可能性を感じる。MacOS8の頃から音声読み上げは簡単にできていたけれど、こんなこともできますねえ、ぐらいで、その頃は実用になるとは思えなかった。今は、iPodを使えば、歩きながら聞くことが出来る。現代のように、まとまった時間を取りにくいサラリーマンにとって、重要なツールの一つなのかも。


 一番欲しいのは、詩や本の朗読、ラジオドラマの音声ファイル。特に、詩は読むよりもリズム感があり、すごくイメージしやすい。ネット検索してみたが、まだ発展途上の状況で、まだ量が少ない。


 最近の僕のお気に入りは、下記の「今夜の一冊~湘南BeachFM Relaxin'Mode 今夜の一冊」。


 金子みすヾさんの詩の朗読などもあり、すごくいい!


 童話や詩は、子供に本を読み聞かせるものだから、Podcastのような使い方が一番似合っている気がする。


| | コメント (0) | トラックバック (1)

2006/01/16

オブジェクトはサーバーみたいなもの

 OGISのオブジェクト広場に記載された丸山さんのインタビューを読むと、オブジェクト指向とネットワークの相性が良いという感想を持った。

やはり丸山さんのご関心はどちらかというとインフラに近いんですか?

ネットワークが好きなんですよ。なぜかと言うと、これからはネットワークが一番の基本になるというのが僕の考えだからです。
コンピュータからネットワークへという大きなパラダイムシフトが進むだろうと考えているんです。
よくコンピュータサイエンスと言いますけれども、コンピュータは 20 世紀の技術で、これからはやはりネットワークの時代だと思います。
だから、ネットワーク上のオブジェクトを扱うプログラム言語みたいなものが出来てきたら面白いと思うんですよね。
僕が、あと 30 才か 40 才若かったら、そういうことをしたいですね。

 インタビューを読むと、丸山さんはネットワークプログラミングからオブジェクト指向へ進んでいったことが分かる。
 GUIアプリを作るとか、Smalltalk使いではなく、Webプログラミングからオブジェクト指向に進む方が、自然ではなかろうか?

 何故なら、オブジェクトはサーバーみたいなものだから。
 つまり、他のオブジェクトからリクエストを受け取り、オブジェクト内部で処理してレスポンスを返す。呼び出し側のオブジェクトは、その間ずっと待機している。
 これはまさにイベントドリブンと同じ構造を持つ。イベントが発生するタイミングは、ブラウザの画面更新時に対応する。

 そう考えると、メッセージパッシングをWebのRequestとResponseの操作のアナロジーと考えることもできる。
 だから、そのアナロジーを発展させれば、Webの処理に時間がかかるなら処理オブジェクトそのものを切り出して生成&実行するProxyオブジェクトや、リクエストのパラメータに応じて処理を動的に変えるCommandオブジェクトが必然的に現れる。
 
 オブジェクト指向の説明として、動物の鳴き声の例とか、手続き型プログラミングとの比較とか、給与計算の例とか色々あるけれど、Webという舞台装置による説明が一番しっくり来るのではないかと思う。
 丁度、JavaがWebの爆発と共に発展していったのと同じように。
 

| | コメント (0) | トラックバック (0)

2005/11/22

プログラム=インターフェイス+アルゴリズム+データ構造

ここの記事「「アルゴリズム+データ構造=プログラム」? 本当に?」がすごくホットで面白い。

普通、IT業界に入社した当初は、現実世界をコンピュータ上へシミュレートする時、全てのロジックを構造化された形式に直すのがSEの仕事だと習う。
まさに、アルゴリズムやデータ構造を考えているのと同じ。

プログラマは、インターフェイスよりも、アルゴリズムを考えたり、データを保持するためのデータ構造を考える時が多い。

インターフェイスは、設計者によって既に作成され、プログラマは設計書に従ってコーディングする時が多い。

だから、インターフェイスを考えるプログラマは少ないのでは?

昔のFortrunやBasicのプログラムを読むと、ローカル変数が存在せず全てグローバル変数とか、サブルーチンが存在せずGoTo文しかないとか、今では考えられないような制約があった。
その頃の考え方の遺産が「アルゴリズム+データ構造=プログラム」。

最近何故かVBを仕事でやらされているが、JavaやC#がいかに書きやすいか、まざまざと感じさせられる。

・型チェックが弱い。コンパイルしても、実際に動かさないと、コンパイルエラーすら見つからない!!
・実装継承がないのでポリモルフィズムが使えない。Case文がやたらと多い。
・例外処理がないので、GoTo文を使うしかない。
・Formに全てのロジックを書いてしまっているために、シーケンス図で書くと、肥大化したクラスそのものになってしまう。
・クラスを使うロジックが少ないため、関数の引数がやたらと長い。
・関数の引数に戻り値を渡す書き方が多いため、混乱しやすい。
・VBはFTP等のネットワーク系ライブラリが使いづらい。
・Collection等のコンテナのライブラリの機能が少ないため、基本的なアルゴリズムをわざわざ実装する手間がかかる。

オブジェクト指向プログラミングは、アルゴリズムやデータ構造をオブジェクトの中に隠蔽してしまい、インターフェイスだけを考えれば良いプログラムが書ける、という発想。
インターフェイスを突き詰めて考えると、複雑な処理は、多数のクラスへ分割され、プログラム構造は階段状のシーケンス図で書き表される。
GoFのデザインパターンは、結局インターフェイス設計を説明しているのと同義。

現代の考え方は「プログラム=インターフェイス+アルゴリズム+データ構造」。

しかしながら、少なくともVBプログラマにはそういう発想はないみたい。
VBなんか、消えてしまえばいいのに。

| | コメント (5) | トラックバック (1)

2005/11/15

Web 2.0メモ

 最近、巷で流行しているWeb 2.0のメモ。

Web 2.0:次世代ソフトウェアのデザインパターンとビジネスモデル(前編)

Web 2.0:次世代ソフトウェアのデザインパターンとビジネスモデル(後編)

 アプリケーションはOSではなくサーバーにあるべき。
 Windowsは古い。
 Googleが生み出すWebのサービスの方が、はるかに刺激的。

| | コメント (0) | トラックバック (0)

2005/11/10

Google Mapsで鈴鹿サーキット試走

面白い記事を発見!

Google Mapsで鈴鹿サーキット試走

Spaceキーでアクセルを踏みすぎたせいか、オーバーランばかり(^^)

当然ながら、JavaScriptを使っているわけか。
ソースをチラリと見たら、GMap、GPointというクラスにX・Y座標や諸々のデータがあるので、いつでも取得できるみたい。

GISのシステムは、実はすごく難しい。
例えば、地図上の距離を計算しようとしたら、直線ではなく、球面上の測地線なわけだし。
GISは地図描写エンジンが鍵を握っている。

Googleはどんなエンジンを使っているのだろう?

| | コメント (2) | トラックバック (2)

2005/11/03

10分で作るRailsアプリ

 最近、Ruby on Railsが熱い。
 ふと見つけた驚異的な記事。

「10分で作るRailsアプリ アプリケーション編」

 Javaを始めた時と同じぐらいのインパクト有り!

| | コメント (2) | トラックバック (0)

2005/10/20

NAgileメモ

メモ。

NAgileで始める実践アジャイル開発

第1回 .NET+アジャイルなら本当に幸せになれるのか?

| | コメント (0) | トラックバック (0)

2005/10/08

Ruby関西勉強会に行ってきた

 第6回 Ruby勉強会@関西へ行ってきました。
 面白かったー。

 関西でもRubyやっている人は多いんですねえ。
 京都女子大で開かれたせいなのか、松江、東京、広島から駆けつけた人もいて、50人も集まって大盛況でした。
 内容は、Rubyでゲームアプリを作る話とRubyのTestUnitを使う話で、業務系システムの話やRuby on Rails、BioRubyに興味を持っていた僕にはちょっと物足りませんでしたが、勉強会の雰囲気がいいし、懇親会も女子大生とか京大生も来て元気だし、楽しかった。

 場所を提供した小波先生と、懇親会でずっと話し込みました。

「Rubyを大学教育で使っているのは、うちしかない」
「以前はPascalを使っていたが時代遅れになった。Rubyならオブジェクト指向にも触れられるし、ソースの可読性が高い」
「プログラミングには、コンピュータの仕組みを知らないと書けない部分と、書きたいロジックそのものの部分の2つがあるが、Rubyなら、後者に意識して書くことが出来る」

 小波先生は教育熱心な先生で、僕も大学時代はこんな先生の研究室へ行きたかったな、と思ってしまった。。


| | コメント (0) | トラックバック (0)

2005/10/07

.NETよりもJavaの方が面白い

 .NETは面白くないなー、と違和感を感じつつやってます(m_m)
 オブジェクト指向設計とか、AAfNによる3層構造とか、Webサービスとか、技術的には面白いのですが、Javaと違うなーという点がすごく多すぎな気がしてます。

【1】オブジェクト指向をやっているという感覚よりもWindowsAPIを必死に覚えている感じ

 C#、ASP.NET、VB.NETをやると、確かにプログラミングはオブジェクト指向っぽいけれど、何か感覚が違う。
 昔C++をやっていた頃、C++をやっているのではなく、MFCライブラリを必死に覚えているのと同じのと同じ感覚に近い。
 プロパティ、イベント、デレゲート、属性、など、Javaよりも優れている部分は確かにある。
 でも、フォームを作って、コントロールをペタペタ貼り付けて画面を作っていく操作に、オブジェクト指向設計を意識している人は多いのだろうか?

【2】.NETは、昔のVBで作ったC/Sシステムの置き換えの延長にあるから、ややこしい

 レジストリに登録したり、COMを使ったり、仮想ディレクトリを設定する時にセキュリティレベルを考慮したり、Windows特有の環境構築が面倒なことが多い。
 つまり、昔の遺産(VB資産)があるので捨てられないのではないか? 実際の案件でも、過去にVBやAccessでやっていたシステムを.NETで置き換えるシステム開発は多い。。
 .NETを使う最大の理由は、VB資産を再利用できる所にあるからだろう。
 でも、ネックになるのは、COMじゃないだろうか? .NETで作ったDLLは、Javaのjarのように自然に使えるのに、COMだと使いづらい。
 Javaなら、過去の古い資産はないから、簡単なのかもしれない。

 MSツールの理想系は、C/Sシステムではなかろうか?
 リッチクライアントはその流れにあるのではないか?
 C/Sシステムは、本質的に2層構造にならないか?
 以前のASP(VBScript)のシステムは、開発者が設計を意識しないと2層構造のアーキテクチャになり、ぐちゃぐちゃになる。
 ASP.NETは、AAfNのおかげで3層構造を意識させられるけれど。

【3】何故、いちいちコンパイルするのに、必ずビルドボタンを実行しなくてはならないのか?

 Eclipseを使っていた人から見ると、保存(Ctrl+S)でコンパイルしてくれなくて、いちいちビルド(F5)を幼くてはならないのは、違和感がすごくある。
 プログラミングは、やっぱり書きながら、ああだこうだと考える部分が多い。だから、リファクタンリングをよくするけれど、その作業はサクサクやってほしい。考える作業を邪魔する作業はなくして欲しい。
 こんなことを感じるのは、かつてVBでえらい目に遭った僕だけだろうか?


 僕がJavaに惹かれるものは、「なぜJavaにこだわるのか」の記事と全く同じ。
 Javaを突き詰めることは、IT業界の最新技術を追いかけるのと同義。オブジェクト指向をマスターすることにつながるし、更には、開発プロセスやオブジェクト指向設計、デザインパターン、ビジネスモデリングまでつながる。すごく面白い。
 Javaには「愛嬌」がある。全くその通り。興奮させられる所がある。
 オープンソースを探してみれば、Javaの方がはるかに多いし、ERPやプロジェクト管理など、とてもフリーとは思えない業務システムも転がっている。
 全ては、プログラマがJavaの潜在力を知っていたから。

 .NETやJavaを比較すると、開発環境もプログラミング・スタイル以上に大切であるように思う。
 丁度、SmallTalkでも、ガベージコレクションなどオブジェクト指向開発環境が表裏一体であったように。

| | コメント (4) | トラックバック (0)

2005/09/30

.NETをやっていくためのTODO

 Java一筋だったのに仕事でC#をやっている(m_m)
 プログラミングも設計もやり方はJavaと同じだけれど、何か違和感を感じつつやっていて気持ち良くない。
 .NETを今後やっていくために理解すべきタスクをリストアップしておく。

【1】NUnitでUnitTest

・VisualStudioと組み合わせたテスト環境
・Javaにはない.NET特有の注意点
・NAgileを調査

【2】Application Architecture for .NET (AAfN)に学ぶ.NETシステム設計

・J2EE Blueprintsにある設計思想とどのように違うのか?
・J2EEのPetShopとの違い
・O-Rマッピングは.NETでは問題にならないのか?

【3】次世代開発基盤技術“Software Factories”詳解

・Software Factoriesの思想はパッケージ製品の設計・開発にどれだけ役立つか?
・開発プロセスとの関連
・VisualStudioの次期バージョン調査

 ネットで検索しても、@ITやGotNetぐらいしか有用な情報がない。
 色々いじってみた所感では、.NETはJavaよりも技術が枯れていないな、と感じる。
 本当のところはどうなのだろうか?

| | コメント (0) | トラックバック (0)

2005/09/06

ITの技術革新はOSよりもWebソリューションへ移っている

M$が次期WindowsOS Vista を来年に売り出すらしいが、盛り上がってないように見える。
理由は、OSの技術革新の衝撃が薄くなっていて、むしろGoogleのようなWebソリューションへトレンドが移行しているからではないか?

WindowsOSやOfficeのバージョンがUPしたからといって、我々ユーザの環境が劇的に変わるわけでもない。バージョンアップを煩わしいと皆呟いている。
ActiveDirectoryの導入で余計に手間がかかっていないか?

むしろ、Googleが生み出すサービスの方が我々のWebの使い方そのものを劇的に変化させている。
例えば下記のサービスがある。

1.容量1GものWebメールサービス GMail
2・デスクトップ検索サービス GoogleDesktop
3.地図検索サービス GoogleMaps

【1.容量1GものWebメールサービス GMail】
GMailをまず使ってみて驚いたのは、勝手にリフレッシュし、メール一覧を更新してくれること。
さすがAjax。

【2・デスクトップ検索サービス GoogleDesktop】
以前まで、ローカル内のテキスト・Office・PDFファイルを検索できるようにするために、Namazuをインストールし、定期的にバッチファイルでインデックス検索させるようにしていた。
ActivePerl+Kakashi+Namazuを入れて、日本語で検索できるように設定するために結構手間取った。
GoogleDesktopなら、ファイルだけでなくメールまで検索で来てしまう。

【3.地図検索サービス GoogleMaps】
GoogleMapsは面白い。
市販の地図情報システムは今だにC/Sアーキテクチャの古いシステムが多く、有料のため使っていて楽しくない。
記事「渺望と俯瞰 :keyhole が 3D地図と検索を関連づけるか:Google Earth スタート」ではGoogleMapsの威力を下記のように説明している。

(引用開始)
(前略)
GoogleMapを見ればわかるが、日本の地図表示・検索サイトよりも遥かに豊かな情報が関連付けて閲覧できる。
1.Mapまたは衛星写真
2.現在のレストランなどのWebコンテンツ
の2つを、検索エンジンが、位置座標と関連付けてView+スクリプト表示しているだけである。
一方、多くの一般の地図サイトは、なんと時には有料で、サーバーに入力させて、(労力と費用を使って)、ほとんどのレストランが参加していないレストランガイドサイトとなっている。
このGoogleMapと同様の機能をMyサーバー上に、実現できるのが GoogleWebAPIである。思わぬアイデアが出現しそうなので、お楽しみである。
(引用終わり)

つまり、日記を手軽にUpできるBlogのように、自分オリジナルのレストラン地図とか、自分の地区の選挙マップとか作れる。

例えば、GoogleMapsEditorを使えば、こんなに簡単に地図が作れてしまう。

なにわのお笑い劇場:ワッハホール

他にも、AmazonのWebサービス、ライブドアが提供したWikiサービス、Skypeもワクワクする。

次から次へと現れるWebソリューションに触れると「IT技術は、コスト削減のようなつまらないことに使われているが、本来は、新しい産業を生み出すことに使われるべきだ」とXP祭り2005で講演したM$の萩原さんの意見を思い出させる。

| | コメント (1) | トラックバック (0)

2005/09/02

非同期処理のアーキテクチャとは

最近、リッチクライアントが流行している(ように見える)。
理由は、UIの操作性よりも、非同期処理の実現にあるのではないか?

Webの技術では同期処理が基本である。HTTPのリクエストを投げてレスポンスを待ちページを表示する。
だから、WebはUIの操作性だけでなく、技術的にも制約が大きい。

非同期処理は、つまりバッチ処理。
業務系では至極当然のアーキテクチャ。
バッチ処理は設計力が鍵を握る。

Web上での非同期処理の実現方法は何がBetterか?
答えはWebサービス。
つまり、クライアントはXMLデータをバックグラウンドでサーバーとやり取りする。
Googleがこのアーキテクチャをうまく使ってサービスをどんどん提供している。

Ajaxの凄さは、UI操作性だけではなく、非同期処理にある。
Ajaxの威力を見せつけた例は、Google Mapsだった。

GMailは、勝手にリフレッシュし、メール一覧を更新する。
GMailにもAjaxが使われている。

GoogleMapsEditor は、GoogleMapsAPI を利用して地図を作成する。
ユーザが住所と関連付けて書き込んだ情報はローカルのXMLに保存される。
すごいのは、そのXMLを使うと、地図情報を埋め込んだ出力したHTMLファイルだけでGoogle Mapsが利用可能になること。
一般に地図情報システムは、クライアント:VBアプリ+サーバー:ベンダーごとの製品ゆえ、非常に高価で、バッチ処理が基本なのでレスポンスも良くなく、使い勝手が悪い。Google Mapsは、普通の地図検索製品よりもはるかにお手軽でしかも無料で地図を作れるサービスと技術を提示したことに意義がある。

他にも、Blogがある。RSSはWebサービスそのもの。
つまりプッシュ配信サービスと言ってよい。

Webソリューションの進化系はおそらく非同期処理のアーキテクチャを洗練させることにあるのではなかろうか?

| | コメント (2) | トラックバック (1)

2005/07/16

再帰SQL part2

yuuntim さん、半年前に書いた記事「再帰SQL」のコメントありがとうございます。
最近はOOAからどんどん離れて業務屋さんになった経験も踏まえて、もう一度考えを整理してみます。

【1】再帰SQLはツリー構造の情報を検索する時に使える

あの時は再帰SQLの意味や使い道が全く分かっていなかった。しかし、今の仕事のおかげで、再帰SQLは重要であり、色んな所で使えることを経験した。
再帰SQLが使われる具体例は二つすぐに思いつく。
一つは、個人の組織情報が階層構造になっている場合、もう一つは、商品がカテゴライズされていてカテゴリ情報が階層構造になっている場合だ。
組織構造の例は、アナパタのパーティそのもので、再帰構造になっている。
どちらにせよ、組織マスタとかカテゴリマスタのテーブルに階層構造の情報がツリー構造で保持されている時に有効になる。
但し、当然のことながら階層が深いほど、再帰SQLのレスポンスは悪くなる。

【2】再帰SQLはOracleでは普通に使われている
Oracleでは、CONNECT BY 句を使えばよい。
例えば、下記の例は良く出てくる。

--job='PRESIDENT' が、親子関係の頂点で、親子関係は empno=mgr が条件である従業員を検索する
select empno,level,lpad('-', 2*(LEVEL-1),'-') || ename ename ,mgr,job from emp
connect by prior empno = mgr start with job='PRESIDENT

余談だが、connect by 句はSQL本をいくら漁ってもなかなか出てこなくて、調査に随分苦労した。ツリー構造のデータなんて、生産管理でも良く出てくるのに、何故解説がないのだろう?
実はSQL ServerやDB2では上記SQLは使えないし、再帰SQLも最近までサポートされていない。Oracleだけver8以前からもサポートされていたらしい。さすがOracle。

【3】「生産管理・原価管理システムのためのデータモデリング」再考
今頃になって読み返して、まだ理解できていない点はありますが、少しずつ腑に落ちつつある。

「部品構成のループのチェック」についてすぐに思い浮かぶのは、ツリーを深く下がって検索する時に最下層がどこまでなのかを既に把握できていれば、計算しやすくなるはずだろうということ。
だから、構成品の削除・更新があるたびにLLCを再計算しているわけだ。これは確かに重い処理だと思う。

「所要量計算(あるいは原価計算)を行う品目の順序を決定する」処理の解説、yuuntim さんありがとうございます。
親品目の所要量の総計が計算できた後に、下層の品目の計算を行うために、LLCの昇順で降りていくわけですね。なるほど。この計算はすごく重たそう。
MRP所要量計算のアクションダイアグラム(P176参照)はPL/SQLで書いたとしたら、一時変数のカーソルでループ処理するために、すごく読みにくいだろうなあと勝手に想像します。

この本はまだ奥が深いです。また読み直します。

最近はクラス図よりもER図を片手に仕事する時が多い。仕様を理解できない時、ER図からインスタンスごとのリレーションを結んで、データがどのようにつながっているかを自然に書き散らすようになった。その感覚はオブジェクト図を書いているのと同じ。
データモデリングだろうがオブジェクト指向モデリングだろうが、やっていること、考えるやり方は結局似ている気がする。

| | コメント (0) | トラックバック (0)

2005/05/05

Smalltalkにはif文がない

 「Smalltalkにはif文がない」記事を読んで、なるほどと腑に落ちた。
 SmalltalkではTrue・Falseクラスがあるのは知らなかった。
 IF文もWhile文も全てメソッド、ブロックで実現できてしまうのか。

 「プログラミングの基本はIF文を極力排除する」記事と同じく、オブジェクト指向の良さは、ポリモルフィズム、イテレータにあると思うが、それらは結局、IF文、While文を除去する方向へ進化している。

| | コメント (5) | トラックバック (1)

2005/02/25

システム開発のボトルネックはメインフレームに有り

 システム開発のボトルネックは、メインフレーム(ホスト)の存在そのものにあるのではなかろうか?
 JavaでWebシステムを開発していると、いつもそんなことを感じてしまう。

 どこの大企業に行っても、必ず10年以上稼動し続けているメインフレームが既に存在している。メインフレームなしでは企業活動そのものが存続できないようだ。最近の流行であるそのメインフレームをオープンシステムへリプレースすることは、どこの大企業でも殆どありえないように見受けられる。
 そもそも何故メインフレームが存在するのか、本当の理由を僕は知らないが、とあるBlogでは、「企業の基幹システムは最終的に財務諸表を作るために存在する」と書かれていた。
 しかし、財務諸表や損益売上決算書などは、オープン系システムでできないのだろうか?

 普通、どこの大企業でも、メインフレームは顧客データや請求・契約などの会計に関するデータを管理している。つまり、企業にとって死活的に重要なデータは、必ずメインフレーム内で管理している。
 いくらOOAをフルに使ったWebシステムを作ったとしても、Webシステムは、集めた受注データをホストへ送り、入出荷や請求のデータをホストからもらうだけ。業務的には、入り口のシステムに過ぎない。
 Webシステムがダウンするのは当然困るが、企業活動そのものが止まってしまうわけではない。

 僕がメインフレームを毛嫌いする理由は、OO技術者にとって、メインフレームがブラックボックスだから。メインフレームでデータをどのように加工し出力しているのか、全く意味不明だから。

 更に、ホストとのやり取りのために、無駄なインターフェイスが必要になる。
 例えば、受注データをリアルタイムにホストへ送信したり、月次請求や四半期決算のデータをホストから特定の日に受信する処理がある。
 仕組みとしては、ホストはバイト長データしか扱えないため、バッチプログラムがバイト長データを変換してRDBのワークテーブルに一旦保管し、Javaが扱うテーブルへ移し変える。そのプログラムは、典型的なCのプログラムで、オブジェクト指向以前の古い設計に基づく。しかもテストしにくい。

 オブジェクト指向をフルに使った設計やオープンソースのフレームワークを適用したオープン系システムを開発しようとしても、結局、メインフレームとの整合性を取るためのシステムテストがボトルネックになる。
 何しろ、受け入れテストに必要なシナリオやテストデータを洗い出し、実際の業務をシミュレーションするために、1週間とか1ヶ月も時間を費やす。オープン系システム内部で閉じたシステムなら、システムテストは楽なのに、ホストと連携するテストを行うために、無駄なコストがかかる。

 「メインフレームはオープンシステムに取って代われる」という記事を随分昔から見てきたけれど、未だに実現されているとは思えない。それらの記事は、単なるデマだったのだろうか?

【参考記事】「5年後,メインフレームはなくなる」 日経コンピュータ2003年3月24日号

 IT業界に入って、結局いつもぶち当たる壁は、ORマッピングとメインフレーム。
 それらを再考し直すと、結局、メインフレーム・RDB・オブジェクト指向プログラムの3つはどれも思想的に全く異なるシステムであって、それらのインターフェイスを合わせる為に、ORマッピングやバッチプログラムという無駄な中間レイヤーが必要になる。
 企業システムとは、結局、これら3つの相容れない混合システムであるべきものなのか?
 多分そうでないはず、と思うし、皆そう感じているのではなかろうか?

 メインフレームが今もなお存在する理由は、IBM・NEC・富士通・日立等のような大手ベンダーが過去あるいは今までメインフレームを製造し続けてきたからだろう。
 メインフレームというハードを中心にしたビジネスが長らく続き、そのビジネススタイルからなかなか脱皮できない所に原因がある気がする。

| | コメント (8) | トラックバック (2)

2005/02/02

テスト・ビルドプロセスの重要性

 最近のシステム開発の傾向を眺めると、テストやビルドプロセスを重視しているのが分かる。

 ウォーターフォールモデルでは設計や実装を重視するが、アジャイルやMSの開発フレームワークはテストやビルドを重視している。
 そのような傾向が生じた理由は、開発のボトルネックが、コンピュータ・リソースではなく、いかに変化に対応できる環境を作るか、へ移ってきたからだろう。
 そうなると、作ったシステムの正当性を保障するテストプロセスや、作ったシステムを安定稼動させるビルドプロセスがおのずから重要になってくる。いくら設計や実装をしても、早く実際に動かしてみなければ無意味になる状況が多くなってきたのだろう。

 更に理由の一つとして、テスト・ビルドの技術が面白く、実装と同じレベルのプロセスに組み込めるから、開発者でもテスト・ビルドプロセスに関心を持つ方向へ誘導できるのではないか?
 開発者の視点から眺めると、最近のテストプロセスやビルドプロセスは技術的に面白い。
 テスト駆動の技術としては、モックオブジェクト、プロキシ、リフレクション等の高等技術がふんだんに使われている。
 ビルドプロセスなら、AntやMavenなどがあげられるだろう。特にMavenは、プロジェクトが一つのコンポーネントに対応している特徴があるが、それはオブジェクト指向の再利用性の話につながる。
 
 Mavenの根底にある思想は、プロジェクト管理につながるように感じる。
 Mavenについては、もう少し調査してみたいと思う。

| | コメント (2) | トラックバック (0)

2005/01/24

継承→Aspect→DI へプログラミング言語は進化している

 オブジェクト倶楽部の定期MLで、「オブジェクト指向の再定義」と題して平鍋さんが連載記事を書かれているが、すごく面白い!
 記事の中で印象に残った言葉は、下記の二つの文章。

EoT(Ease of Testing、テスト容易性)の高い設計が、よいオブジェクト指向設計である
EoC(Ease of Changing、変更容易性)の高い設計が、よいオブジェクト指向設計である

 オブジェクト指向言語のあらゆる機能は「テスト容易性」を実現するためにある、と言い切っている。実際、下記のことが思いつく。

1.MockObjectを作るには、無名クラスで実現するために継承を用いる。
2.インターフェイス優先は、テストしやすくさせるため。
3.パッケージ循環依存性を排除するのは、テストしやすくするため。
4.オブジェクトの責務割り当ては、テストしやすいモジュール分割をするため。

 更に、「再利用性」よりも「変更容易性」の方がオブジェクト指向設計で重要だと主張している。最近のアジャイル開発の流行を見ると、そのことを強く感じる。プログラムの変更リスクが低い方がはるかに変化に強い。
 一昔前はコンピュータやネットワークのリソースが高価だったため、変化への対応能力はあまり重要視されていなかった。でも今は違う。変化に強くないと、プログラムの品質そのものも低下するから。

 変更容易性を実現する技術が、継承や委譲だったり、最近ならAspectやDIだったりする。それらの技術を比較してみると、「継承→Aspect→DI」の方向へプログラミング言語が進化しているのが分かる。

A.継承・・・実装時に既に依存関係がある。最も強固な依存関係ゆえ、できるだけ避けるべき。
B.委譲・・・OOでは継承よりも良いと言われるが、無駄な空メソッドが増える。
C.Aspect・・・コンパイル時に依存関係ができる。プログラム同士の依存関係はないが、バイナリ同士には依存関係がある。
D.DI・・・・ランタイム時に依存関係ができる。プログラム同士にもバイナリ同士にも依存関係はない。

 ランタイム時に依存関係ができるということは、パソコンの組み立てと同じく、プログラムを部品と見なすことができることを意味する。インターフェイスさえ合致していれば、いくらでも部品を組み合わせることができる。
 とはいえ、プログラムではインターフェイスを合わせることに四苦八苦することが多いが。。。

 平鍋さんの記事を読むと、プログラミング言語の将来像について深く考えさせられる。

| | コメント (0) | トラックバック (0)

2005/01/23