ゆえあって年明けからspringを使うので勉強メモ
第1章 SpringとWebアプリケーションの概要
オレオレWebアプリケーション設計論。要る?一般論としては中途半端。知らない人には理解できない話だろうし、知っている人は「言いたいことは分かるけどプロジェクトによって違うだろ・・・」って話。フレームワークに依存した話なら「spring使うときはこうやって設計すると効率的」の方が分かりやすい。「こういう理想があってそれを実現するための諸々の面倒くさいことを肩代わりしてくれるのがspringなんだよ!」って伝えたい気持ちは分かる。
第2章 SpringのDI
WebアプリケーションのDIコンテナ
実装が一つしかないインタフェースを定義するところがかっこ悪い。プラグイン機構としてのDIならいい。2007年のSeasarブームの時に感じてたDIに対するワクワク感はなんだったのか・・・。
インスタンス生成がSingleton
記述がやたら出てくる。インスタンス生成のコストなんて多寡が知れてるだろうにそんなに重要?と思ったがASP.NETでもServiceとDAOはstaticクラスで実装している。(メソッドをまたがる)状態を持たないのでインスタンス化する必要がない。Javaにもstaticクラスがあればいいのにね・・・。いずれにせよDIを使う以上インスタンス生成は必要なので原則Singletonでよさげ。「ServiceやDao以外のインスタンスをDIコンテナから取得したくなった時にSingleton以外の生成方法も可能」だって話ね。とりあえずそんなシチュエーションは思いつかない、大抵は依存性を注入する必要もないだろうからnewすれば事足りるはず。フレームワークだから逃げ道は大事だよね。
JUnit4のassertEquals
ProductクラスがEqualsを実装していないのにassertEqualsでインスタンス同士を比べている。もしかしてJUnit4て中身比べるようになっているの?もしそうなら一体何を見ているんだろう?publicなgetter?
Mockに差し替え
どうやってやるのかな?そのうち出てくるのだろう。
第3章 SpringのAOP
AOP活用のサンプル
connectionの生成とtry-catch-finalyがなくなったのでAOP凄いでしょドヤァとか言われてもだな。いい加減usingを実装しろ!今ではtry-catch-finalyが呪いの句にしか見えないんだ。でも、コネクションの取得と解放がロジックからごっそりなくなるのは良い。
トランザクションの中断
ロジックからトランザクションを参照できないと、ロジックの途中でRollbackしたい時は例外投げるしかないのかな?なんて例外投げればいいんだろう?まあ、そんなこと滅多にないか。
コネクション取得のタイミング制御
複数DB間のデータ移行処理とかで、参照DBからのデータ取得が終わっってから更新DBのコネクション取得したい時はどうすんのかな?参照用と更新用の二つにServiceクラスを分ければいいか。
第4章 データアクセス層の設計と実装
DAOパターン
- J2EEの系譜だけあってDAOパターン。
- DAOパターンのメリットをDBアクセスのコードが長いからって言われても引くよねぇ…。PreparedStatementやResultSetをクローズしなきゃいけないのもSQLExceptionが検査例外なのもJDBCの仕様がクソだから。とはいえその辺が解決されているC#でも活用してるからDAOパターンは使うべき。
- データアクセス方式を丸ごと変えることは滅多にないけど、テーブルのカラムが増減することはよくある。その時の変更がDAO、DTO、UIだけでビジネスロジックに及ばないっていうのは動作確認するときに、画面に表示されていてデータベースに格納されていることを確認すればいいと明確になるので助かる。
- DAOパターンは実装しやすい。「SQLを実行してDTOに詰めて返すところだけをDAOに実装してください。」って説明をするだけで初めてDAOパターンを使う人でも8割方上手く書いてくれる。これは色々なレベルのプログラマと仕事をしなきゃいけない時にとても重要。
Spring JDBC
- これはAlhambra*1のおじいちゃんだった。初めて対面した。Alhambra自体はS2 JDBCにインスパイヤしたものだけど、今となってはSpring JDBCの方がよっぽど似ている。なので、とても参考になる。
- AlhambraはDIを想定していないので、トランザクションはビジネスロジックで明示的に制御する。Springでトランザクションをどうやって制御するのか知りたいけど、きっと5章に書いてあるのだろう。
- MAPで返すインタフェースもあれば便利だ。外部とのインタフェースがWEBサービスで最終的にJSONで返すならDTOにする意味ない。DataContract付けるならDTO定義した方が楽からも知れない。
- 匿名クラスでSELECT結果をDTOに変換・・・Javaだとそうだよねぇ。ラムダ式使いたい。
- JOINした結果を処理するResultSetExtractorってやる気ねぇなぁ。まあこんなことするくらいならSQL二回発行してDAOで親クラスにsetすればいいよ。パフォーマンスが問題になったときだけ使うべき。
- updateってメソッド名はどうなんすか?とおもったけどJDBCのexecuteUpdateってメソッド名と対応しているのか。
- batchUpdateもパフォーマンスチューニング用ですね。正直SQL文の発行を多少まとめても、INSERT/UPDATEのDISK IOの方が遅いからそんなに性能は変わらない気がする・・・。まあDBサーバとの通信が遅いとかFusionDrive積んでるとかサーバ構成次第。AlhambraはSQLを一回文字列に変換しているので複数SQL専用のAPIは用意していない。これもADO.NETとJDBCの違い。ADO.NETは常にpreparedStatemen相当の動きなので。
- プロシージャコールのAPIも格好悪い。preparedStatement無視していいならuupdateで代用できるんだけど、APIとして分かりづらいんだよね。
JNDI
JNDIを使用してアプリケーションサーバからデータソースを取得って、J2EEっぽくて面白い。
第5章 ビジネスロジック層の設計と実装
Serviceのメソッドにトランザクションを追加する設定方法が一通り書いてある。
- 伝搬属性:他のメソッドから呼ばれたときに新規トランザクションを作るか既存のトランザクションを使うか
- 独立性レベル:Dirty Readを防ぐとか
- ロールバック例外:どの例外が上がったときにロールバックするか
- コミット対象例外:どの例外が上がったときにロールバックせずにコミットするか
なんでDAOにトランザクションを渡せるのか理解できん。