jfluteが「Seasarどう?」って聞かれたら...

気付いたらSeasarのお話

なんだか最近になって、そう、ここ半年くらいですかね、「Seasarはどうなの?」って話を、よくもちかけられるようになりました。

それまでは、Seasar自体は基礎の基礎の土台みたいなもので、わざわざ Seasar 自体の話をすることは逆になかったんですが、ここに来て Seasar の話ってなんだか新鮮です^^。

もう、およそ 9 年くらい前から Seasar を使ってます。よく使っていましたし、今でも使います。Seasarカンファでもたくさん登壇させて頂きましたし、長く付き合ってますので、Seasarに個人的な思いもあります。それはまた今度、別エントリで書きましょう。

それだけに、やはり Seasar のことを聞かれることが多い立場ではあります。(ぼくは Seasar 本体のコミッタではありませんが...)

まあ、Spring FrameworkJavaEE と厳密に比べたわけではなく、色々聞いてると、もう絶対的優位はない!? というか、すっかり離されてる部分も多いだろうと想像はするのですが...(Seasar自体は長いこと特に変化はしていないですからね)

その実績から、決して悪いものではないことはよくわかっていて、「Seasar使う」って人がいれば「うん、いいんじゃない」って感じではあります。

...
...
ただ、ただ、ただっ、たーだ、確かに、よーく考えると、

「わりと素直には使ってないなぁ」

というところもあるので、手放しで「いいね!」にはならないのかもと。

だから、ちょっと整理しないとかなーって。

DB周りは...

Seasarを使うとか使わないって話をするときは、その上で動かす周辺フレームワークのお話も、Seasarの話をするときには暗黙に含まれるかと。

主には、O/RマッパーにWebフレームワーク。

まず、DB周り。
そりゃまあわたくし jflute ですから^^、
DBFluteでおしまいです。...すいませんm(_ _)m。

別にぼくが主導するプロジェクトだけでなく、周りのプロジェクトでどんどん使ってくれていたので。(.NET でも DBFlute 使ってたし)

今の現場でも、Spring だろうが Seasar だろうが、その辺は色々とブレたとしても、どちらにせよDB周りはDBFluteを使って頂いています。

なので実は...実は...9年もあったのに...DB周りは、素のS2Daoもやってないし、S2JDBCもまともには使ったことないのですー(><。(まあ、めっちゃ勉強はしたし、使ってる人の話はたくさん聞いたけどね)

というか、勉強したからこそ、そもそも S2Dao (だけ) ではつらいだろうと考えて、S2Dao を拡張し始めて DBFlute になっていきました。(いまや S2Dao には非依存)

S2JDBCが先に出ても、結局はいろいろと拡張して、「DBFluteっぽく」しちゃってたかも知れませんね笑。

Web周りは...

そして、Web周り。
Teedaをよく使っていたんですけど、
その後、時代はすっかり SAStruts になりました。

でも、これまた何気に素のままで使ったことがない...です。もちろん周りではわりと使われていたので色々と話には聞いてて、そして、いざ身近なところで使うとなりましたっ。そこでっ!

...
...
そう、知る人ぞ知る、SAFlute。
-> SAFlute | DBFlute

飛び抜けたことはやってないですが、SAStrutsを素のまま使うよりかは、はるかに良い感じにしたつもり。(現場からの評判はとても良いです)

もちろん、本当は Teeda とか Ymir とかの高機能な機能を取り込んだり、そもそも Struts 依存をやめたいなとかありますが、とりあえずは大きな不満なく開発はできるようになったかと。(というか何かあったらjfluteがすぐに直しちゃうので)

Seasarの使い方という面では...

さて、Seasar自体のお話。

o Dxo や BeanUtil は絶対に使わない
o DtoはDI対象にしない
o スマートデプロイとベタなものを分ける
o Interceptorをあんまり使わない
o S2Unitも使ってない...
o S2ClassBuilderは絶対に使う
o diconにコンフィグ値を埋め込まない
o S2DBCPは「いいね!」
o actionパッケージは使わず、webパッケージに
o フィールドの隠蔽は Eclipse でエラーに

Dxo や BeanUtil は絶対に使わない

これは出た当初から、「絶対にダメー」と思ってて現場に主張し続けたけど、そこは最初はなかなか受け入れられませんでした。(やはり、目の前の5分の単純作業の省略の誘惑は強かった)

でも、使ってたプロジェクトは何かしら「必ず」そこでトラブって、今では少なくともjfluteの周りでは使ってる人は見かけない。

「なんで Dxo だめなんだ?いいじゃないか!」って言ってた人が...「あれはダメだ、ああいうのはダメですよ」って笑。最初あんだけ反論してたのにー^^。まあよかったよかった。

そのパターンが、プロジェクトや会社をまたいで何度もあって、行くとこ行くとこでjfluteは同じことを言い続けている感じです。

最近では、DBFluteのドキュメントで盛大にダメだと言ってます^^。
-> EntityとDTOとの詰め替えは地道に | DBFlute

DtoはDI対象にしない

Dto は自分で new します。そんな強いきっかけがあるわけじゃないですが、その方がわかりやすいから!? くらい。

なので、DtoCreatorは必ず外します。というか、そもそも Dto って名前自体をあまり使わないかな。何に対する transfer なのかがはっきりしなくって、Dtoがいたる所に氾濫するので、レイヤごとにちょっと違った意味を持たせたりとかしますね。

スマートデプロイとベタなものを分ける

スマートデプロイ管理するコンポーネントのパッケージと、そうじゃないコンポーネントのパッケージを明確に分けます。(そうじゃない: ベタにdiconに登録するコンポーネント)

最初は、同じにしちゃっていました。別にしちゃっても平気は平気なんですけど、なんだか LinkageError や ClassCastException が起きて...HotDeploy がとあるときに効かなくなったり...(そのときはすぐに Tomcat 再起動って条件反射のように)

NamingConventionで厳密にIgnore設定すればOKなのかもですが、混在してるとですね、どうしてもスマート外からスマートなクラスを参照されてしまうので、それよりは分けちゃった方が世話ない。

それでも事故がおきないわけではないですが、明確に、画面やロジックのプログラムと、業務独自のフレームワーク(共通部品)を分けることで、HotDeployトラブルはほとんどなくなりました。

そういうことで、Seasarの強みである HotDeploy をしっかりと享受できるように。いやはや、やっぱりうれしいですよ、これは。

Interceptorをあんまり使わない

まあ、Actionクラスに関してはって感じですが、
ActionCallback で代替します。
-> SAFlute - ActionCallback

Interceptorは確かに便利です。なのでその分、Interceptor地獄をよく見かけるので。(StackTraceもとても追いづらいし)

あと、アノテーション規約方式の Interceptor も使いません。ただでさえわかりにくい Interceptor なので、そこはdiconで明示的な方がわかりやすいかなって。

S2Unitも使ってない

ゆ、ゆ、UTFluteってマニアックなやつ使ってます。。。
-> UTFluteでいろいろ | jfluteの日記

もちろん、UTFlute は S2Unit をヒントにさせて頂いています。その上で、以下のような感じの UnitTest ライフが送れるように。

o テストデータは、ReplaceSchemaであらかじめ用意する
-> テストケース管理のエクセルでデータは作らない
-> テストケースごとにデータ登録するとテストがすごく遅い
-> DB変更時のデータ修正量が半端じゃない

o DIコンテナのインスタンスは、JUnit起動単位でキャッシュ
-> テストケースごとに起動するとテストがすごく遅い
-> テストデータの一元化と合わせると、すごく速く実行できる

o newしたインスタンスにDIができるようにしている
-> これはまあ、UTFluteのページを読んで

UTFluteを作ったのはそんなに昔ではないので、その昔は S2Unit 使っていましたが、色々とやりづらいところがあって、いつもいつも拡張。結局、えーいと UTFlute になったという感じです。

S2ClassBuilderは絶対に使う

これ無しでは、Seasar使おうとは思わないくらいの存在感。
-> S2ClassBuilder | DBFlute

Eclipseプロジェクトが一つだけ」のプロジェクトなんて、実務のアプリ開発では滅多にありません。

フレームワークの拡張にせよ、業務の共通diconの拡張にせよ、diconコピー拡張は絶対にやりたくないものです。(というか、Spring Frameworkにも欲しいんだけど、ないのかな!?)

ただ、Seasar本体には組み込まれていないので、明示的に「使う」としないといけません。いまの現場のプロジェクトでは、必ず使っています。というか、SAFluteはこれを使うことを前提にしています。

diconにコンフィグ値を埋め込まない

これも絶対にやりません。SAFluteでは、jdbc.diconすらも、ローカル・結合・本番で分けるっていうようなことはしてません。diconの環境ごとコピーは絶対にしない。

10個以上のdiconがローカル・結合・本番で分かれていて、ものすごい管理がしづらいってのを見たことがあるので。

diconを設定ファイルとは思ってないんですよね。「コンポーネントの生成と依存関係のロジック」だと。それがたまたま XML になっているだけ。だから、それをコピーするっていうのはロジックをコピーするのと同じ。

コンフィグ値が何も変わってないのに、本番diconを修正しないといけないなんて絶対にいやですね。まあ、納品しておしまいみたいな開発だと別にかもですが、継続的開発の現場だと、絶対に!ですね。

S2DBCPは「いいね!」

厳密に他のDBCPと比べたわけじゃないですが、トランザクション周りがデフォルトで整備されてて、しっかり使えて運用も問題なくいっているっていうのは、これはこれでうれしいなって。

個人的には、ここの部分のソースを読むのは楽しい^^

actionパッケージは使わず、webパッケージに

SAStrutsのお話ではありますが、Actionクラスをactionパッケージに、Formクラスをformパッケージに、

ではなく!

webパッケージに、ActionもFormも入れます。画面表示用Bean(Dto)も、Validatorも。一つの画面で必要なクラスが集まっていた方が管理がしやすいので。

画面依存しないLogicクラスとかだけ、logicパッケージとかに配置します。

フィールドの隠蔽は Eclipse でエラーに

DIコンポーネントのフィールドの隠蔽をすると、スーパークラスの隠蔽されたフィールドにはDIされなくなってしまうという事故があります。もう、Eclipseの設定でエラーにしちゃっています。

どう使ったらいいかな?

パッと思いつくものだけをササっと書いてみましたが...

...
...
ねっ、素直じゃないでしょ^^

という感じで、長い経験の中で培われてきた、

Seasarなら、こういう風に使うかなぁ」

って感じの独自のやり方があって、Seasarのページや本とかで紹介されるオーソドックスな方法、Dolteng で作られる構成など、実は使ったことがないです。

もし、そのまま何もせずオーソドックスなままだったら、少なくともぼくが経験してきた現場と同じ悩みを持つ現場なら、その通りの悩みが発生するだろうと想像しています。

そう考えると、人に「Seasarはどうなの?」って聞かれて、その方法論的なところを伝えずに「いいね!」とは、なかなか言える立場ではないのかもですね。

ただ、Seasarはとても良い「土台」になっていますよ。少なくとも、実装の速さ、そして、変化への耐性、これらが求められる継続的開発の現場では。


...
...
どちらかというと、

「どう使ったらいいかな?」

っていう話の方がしやすいかも^^。