2008年12月13日土曜日

今日の料理

一週間前からからすみの作成に挑戦しています。(*参考1)(*参考2)

ボラではなくタラの卵を(タラコとか辛子明太ではなく生のやつですね)を買ってきて、まずは冷蔵庫で塩漬け。つーか全体的に食い物なの?大丈夫なの?って感じでした。一部緑色してるし(まあ最初からだけど。)。漬けていた間、冷蔵庫はずっと醗酵した魚卵のかほりで充満。腐敗臭ではなく、なんとなくたんぱく質系のまったりとした香りに海の匂いがするというか。人によっては好きな匂いかも。でも結構濃厚で冷蔵庫を開けると毎度ふわあぁんと塩漬け魚卵の匂い。幸い、妻の鼻の調子が悪かったので咎められることはありませんでしたが、う~ん、という感じ。一週間経過した昨日、塩を払って水に漬けました。塩抜きのためです。丸一日ほど塩抜きして、今は日本酒に漬けてます。



週中あたりから外+冷蔵庫で干し始めます。どうなることやら。

もう一つはアジの干物。30cmくらいのむっちりしたアジが一匹97円だったので、もうこれは買わないわけには行かなかったですよ。背開きにしようとしたら思ったよりアジが大きかったので3枚におろしました(相変わらず骨に身が残ってぐやじい(下手だから))。水800ccに対して大匙4杯の塩水+しょうゆと酒を少々(塩加減は水1リットルに対して大匙4杯+-1杯の塩くらいでいいみたい)に1時間浸してから

ベランダで乾燥。よっしゃ。明日の朝はアジの一夜干しでご飯だ。・・・よだれが出る・・・

ベランダに魚がぶら下がってる。いや、シュールな感じがしたのは一瞬だけですよ。すぐに違和感なく認識。というかしみじみとした豊かな気分も。縄文時代のDNAが生きているのだろうか。

サンマも安かったので(一匹58円!)、二匹買って酢で煮たのですが何故か最終的に全面的に焦げ付いてノックアウト。味見で美味かったので悔しさもひとしおでしたよ。明日はリベンジだ。

料理ばっかやってるけど、これが何故かストレス解消になるんだな。

まあ幸せな話だ。
.

DIとかAOPについて考えてみた

フレームワークって何だろう。最近Spring frameworkとかSeasarを試して考えさせられました。

(現時点での感想です。今後評価は変わるかもしれません)

なぜエンジニアはフレームワークを求めるのか。

開発生産性の向上とか、スキルの蓄積とか、そういう一般論やセールストークは脇においておきましょう。

フレームワークとは何か。フレームワークを使うものはフレームワークから使われる。ハリウッドの法則とも呼ばれます。これがフレームワークの本質のひとつです。フレームワークがメインで稼動し、開発者はフレームワークが呼ぶ部品を作る。この部品はフレームワークが定めるお作法に則って作成されなければなりません。つまり開発者はフレームワークが規定する型にハマったコードを書く必要がある。すなわち、フレームワークとは「アプリケーションこうあるべし」と定めるものです。しかも実装レベルで定めます。フレームワークに従わなければ稼動することもできません。

Strutsの目指したものは何だったか。もちろん、Webアプリケーションをシンプルに手早く開発することです。今思えば0.9時代のStrutsの抽象度は低く、またフレームワークにしては強制力が弱く柔軟に過ぎていました。しかしHTMLのインプットフォームをFormビーンにマッピングする発想(抽象化)と、画面遷移とBeanをXMLで定義する設計(疎結合)は非常に先進的であったと思います。

それではSpringの目指すものは何なのか。
Spring is a layered Java/J2EE application platform, based on code published in Expert One-on-One J2EE Design and Development by Rod Johnson (Wrox, 2002).

すなわちロッド・ジョンソン氏が提唱した、アプリケーションのデザインパターンの実装です。細かいところは省きますが、要するにSpringはStrutsとは異なり直接的な何らかの成果物を目標としているのではなく、より理念的なもの(概念と言ってもいいですし、思想、デザインと言ってもいい)を目指しているのです。それがSpringや(恐らくはSeasarも)をとっつきにくくしている理由のひとつであると思われます。

私はこのことが、つまり「目的が抽象的であること」がSpringフレームワークの問題だと思います。なぜか。私はそこにわれわれの業界に付きものの「手段と目的の逆転」が起こっていると見るからです。

なぜSpringを使うのか。Springを使うモチベーションとは何か。Springの位置づけからすると、それは「よいデザインパターンを実装するためである」ということになります。しかしちょっと待ってください。よいデザインパターンを実装するために、われわれはコードを書いているのでしょうか?コードを書くのは、何かやりたいことがあると思います。よい設計のためにコードを書く?そんなことがありえるでしょうか。

確かにオブジェクトをXMLから挿入できるDIや、横断的に割り込み処理をするAOPはよい発想だと思います。しかし、われわれはDIをするためにコードを書いているのではありません。DIやAOPは、あれば便利かもしれないもの。気の利いたスキマ商品なのではないか、と私は思います。例えるなら高級システム手帳。あったらうれしい。使いこなす人はカッコいいと思う。でも・・・別にいらないや。

Spring frameworkを開発する方の熱意と才能はすばらしいと思います。あんなものとても私には作れない。「よいフレームワークを提供して使って欲しい」「いいデザインのアプリケーションを作って欲しい」という熱意はまさに尊敬に値します。

でも私にはSpringは違和感がある。Data Injectionやるためにアプリ作ってんじゃねーや。と思ってしまう。

DBとエレガントに連携し、読みやすいコードで書きたいなら、HibernateやJPA(EJB3.0)を使うでしょう。

Webアプリを効率的に作ろうと思ったら、今の私なら躊躇なくJSFを選びます。

しかし、DIとAOPを使いたいから、XMLでデータや横断的処理を挿入したいからSpringを使うか?使わないと思うな。というかSpringとEJB3.0を連携させる体力の余裕があったら他に回すよね。

ということで、以上が現段階での私のSpring観です。否定的ってことで。

以上
.
(2008/12/15追記)
DIって本当に必要? - ひがやすを blogを見ると、Seasarのコミッタの方も真剣に自問しているようですね。偉い!偉いぞ!!
同じページで、普通の業務アプリケーションにはインターフェースはいらないんじゃないか、と言ってますがこれも偉い!!!よくぞ言った。必要だから使う、ではなく、ただ「インターフェースを使って設計しなきゃいけない」という強迫観念に襲われがちじゃありませんか?こういう問題提起・洞察は非常に重要です。
.

Seasar2を使ってみます(4)

次はAOPです。
わりあいすんなり行きました。

まず自前のIntercepterを準備します。
package test;

import org.aopalliance.intercept.MethodInvocation;
import org.seasar.framework.aop.interceptors.AbstractInterceptor;

public class MyInterceptor extends AbstractInterceptor {

private static final long serialVersionUID = 1L;

@Override
public Object invoke(MethodInvocation method) throws Throwable {

System.out.println("Before");
Object ret = method.proceed();
System.out.println("After");
return ret;

}

}

次はexample2.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
"http://www.seasar.org/dtd/components24.dtd">
<components>
<component class="java.util.ArrayList" name="list">
<initMethod name="add"><arg>"Hoge"</arg></initMethod>
<initMethod name="add"><arg>"Piyo"</arg></initMethod>
</component>

<component class="java.lang.String" name="autoBinding"/>
<component class="java.lang.String" name="useAnnotation"/>

<component class="test.Hello" name="hello">
<arg>list</arg>
<property name="autoBinding">"自動バインディング"</property>
<!-- ダメだった
<property name="useAnnotation">"アノテーション利用"</property>
-->
<aspect pointcut="sayHello">
<component class="test.MyInterceptor"
name="intercepterTest"/>
</aspect>
</component>
</components>

MainとHelloは変更なしです(AOPだからね)。

以上です。(はて、しかしこれをどう使うのかな)
.

Seasar2を使ってみます(3)

次はフィールドインジェクションです。publicフィールドへの自動バインディングとアノテーションを使ったバインディングを試します。

【結論】
自動バインディングは上手くいきましたが、アノテーションはダメでした。なぜだろう??
以下がメモです。
■まず"Binding"アノテーションが存在しない
■Webを調べると"Binding"ではなく標準の"Resource"を使ったほうがよいとのことだったので"javax.annotation.Resource"を使ってみたがダメ。
■@Resource(name="useAnotation")  → ダメ
■@Resource → ダメ
■privateじゃなくprotectedにしてみた → ダメ
■付属のライブラリjarを全部ビルドパスに追加してみた → ダメ
■ダメな理由は結局分からず(なんかすごい恥ずかしいミスをしている予感も)

【作業】
eclipse上でUTF8を入力するために、example2.diconの拡張子をxmlとしています。
(dicon拡張子だとデフォルトエンコーディングのMS932が適用されるらしく、日本語を入力するとSAXExceptionが出るため)

Helloクラス
package test;

import java.util.List;

import javax.annotation.Resource;

public class Hello {

public String autoBinding;

// ↓結局ダメ
@Resource
protected String useAnnotation;

private List<String> listNames;

public List<String> getListNames() {
return listNames;
}

public Hello(List<String> listNames) {
this.listNames = listNames;
}

public void sayHello() {
for (String name: listNames) {
System.out.println("Hello "+name+"! ");
}
System.out.println("Auto binding -> "+autoBinding);
// ↓nullが出るだけです
System.out.println("Annotation binding -> "+useAnnotation);
}

}

Mainクラス
package test;

import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;

public class Main {
public static void main(String args[]) {
SingletonS2ContainerFactory.setConfigPath("example2.xml");
SingletonS2ContainerFactory.init();
S2Container container = SingletonS2ContainerFactory.getContainer();
Hello hello = (Hello)container.getComponent("hello");
hello.sayHello();
}
}

example2.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
"http://www.seasar.org/dtd/components24.dtd">
<components>
<component class="java.util.ArrayList" name="list">
<initMethod name="add"><arg>"Hoge"</arg></initMethod>
<initMethod name="add"><arg>"Piyo"</arg></initMethod>
</component>

<component class="java.lang.String" name="autoBinding"/>
<component class="java.lang.String" name="useAnnotation"/>

<component class="test.Hello" name="hello">
<arg>list</arg>
<property name="autoBinding">"自動バインディング"</property>
<!-- ダメだった
<property name="useAnnotation">"アノテーション利用"</property>
-->
</component>
</components>

以上
.

Seasar2を使ってみます(2)

今度はHelloクラスのコンストラクタからデータを入れてみます(コンストラクタ・インジェクション)。

Helloからsetterを削除してコンストラクタでlistを受けるようにします。
package test;

import java.util.List;

public class Hello {

private List<String> listNames;

public List<String> getListNames() {
return listNames;
}

public Hello(List<String> listNames) {
this.listNames = listNames;
}

public void sayHello() {
for (String name: listNames) {
System.out.println("Hello "+name+"! ");
}
}

}

example2.diconを作成します。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
"http://www.seasar.org/dtd/components24.dtd">
<components>
<component class="java.util.ArrayList" name="list">
<initMethod name="add"><arg>"Hoge"</arg></initMethod>
<initMethod name="add"><arg>"Piyo"</arg></initMethod>
</component>
<component class="test.Hello" name="hello">
<arg>list</arg>
</component>
</components>

Main.javaを一応載せておきます。
package test;

import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;

public class Main {
public static void main(String args[]) {
SingletonS2ContainerFactory.setConfigPath("example2.dicon");
SingletonS2ContainerFactory.init();
S2Container container = SingletonS2ContainerFactory.getContainer();
Hello hello = (Hello)container.getComponent("hello");
hello.sayHello();
}
}

以上
.

Seasar2を使ってみます(1)

適切なTutorialやサンプルが見当たらないため躊躇していましたが、Spring(DIとしての)をいじってみてなんとなくDIフレームワークとやらが分かってきたので、その流れでSeasar2を触ってみました。

元にしたのは以下のページ。これ以上ないほどシンプルなサンプルです。

Human System: The First Seasar2 Example

まあ取っ掛かりとしては十分なんだけど、何も知らない人がこれ見ても厳しいでしょうな。つーかやってみようとすら思うかな?

で、Eclipseにエイヤとサンプルをつっこんで動作確認完了。クラスパスとかパッケージのパスとか基本的なところに注意しましょう(example.diconも暮らすパス上に配置します)。それ以外の注意点は以下の通りです。

▽稼動に必要なライブラリ
s2-framework-2.4.33.jar
commons-logging-1.1.jar
ognl-2.6.9-patch-20070908.jar
javaassist-3.4.ga.jar

▽XMLについて
example.diconから以下の二行を削除しないとエラーコード"ESSR0054"のSAXExceptionが発生して動きません。
</components>
<components>
すなわち
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
"http://www.seasar.org/dtd/components24.dtd">
<components>
<component class="java.util.ArrayList" name="list">
<initMethod name="add"><arg>"Naoki Takezoe"</arg></initMethod>
</component>
</components> <!-- この行と -->
<components> <!-- この行が不要。 -->
<component class="jp.sf.amateras.seasar.example.Hello" name="hello">
<property name="target">list</property>
</component>
</components>

当たり前だけどこれだけではふーん、という感じ。確かにDIだね。みたいな。でもちょっとSpringに比べてプリミティブ?

国産フレームワークということなので、それだけでも応援したいですね。

引き続き調べてみたいと思います。(何やろうかな)

.

2008年12月8日月曜日

偶然とチェ・ゲバラ

図書館で何気なく手に取ったチェ・ゲバラの「ボリビア日記」。チェ・ゲバラって結局誰なんだっけ?という程度の認識でナニゲに借りてしまったのが二週間ほど前でした。すなわち「ゲバラって誰」という認識だった。ゆえに借りてみた。実に薄っぺらいきっかけです。帰ってから妻に「チェ・ゲバラって誰だっけ」と聞くと「えーと、何かキューバとかカストロとかそんな感じ。それ以上のことは知らない」との答え。私の認識はそれ以前でした。

で、読んでみるとなかなか面白い。そうか。チェ・ゲバラってこんな人だったのか。理想に駆り立てられ、世界を変えようとゲリラ活動に身を投じた男。永遠の青春。偶像化されるのも理解できるなあ。日本の学園闘争とか60年代後半もこんな空気が流れてたんだろうな。

ま、それはさておいて「ボリビア日記」を読み始めてしばらくしていたら何やらチェ・ゲバラが映画化される模様。うん。シンクロした。たまにこういうことがありますね。

さて、この偶然をどう解釈するか。人間はなんにつけても意味を見出したい存在なのでいろいろパターンを考えてみる。

1.私が図書館でチェ・ゲバラの本を借りたがゆえに、まさにこの私をターゲットとして映画が作られた。
→ うん。オカシイ人の発想ですな。大体時系列でつじつまが合わない。映画作るのに数年はかかるはずだから。

2.チェ・ゲバラ再評価の雰囲気が以前からじわじわと高まっていた。映画の作成・公開もその流れに沿ったもの。私がたまたまチェ・ゲバラの本を手に取ったのはまったくの偶然。意味はない。
→ まあ、妥当な解釈でしょう。

3.小林多喜二の蟹工船のヒットやアメリカ流資本主義に対する批判的風潮に乗り、次はチェ・ゲバラ関連を売り込もうとして広告代理店がいろいろ布石を打っていた。私も無意識のうちにWebやテレビから触発されており、図書館で「ボリビア日記」を手に取ったのは私の自由意志ではなく、実は広告代理店のキャンペーンの結果でしかなかった。映画化もその流れ。
→ ありそうですが、ややオーバーな解釈。

というわけで、2がメインで3はそういうことも少しはあるかな、という感じですね。偶然っていうのも楽しいもんです。

私が一週間ほど前にカワハギについて書いた後、asahi.comでカワハギが出てきたのもまた別のシンクロ。カワハギの旬が冬だって理由はあるでしょうが、やっぱり楽しい。

以上
.