ActiveObjectsの変態的な考え方にまたまた驚愕
正式リリース前のせいか、まともなドキュメントは見当たらないActiveObjects。でも面白い機能が多いせいか、いろんなところで取り上げられているみたいですね。その中でも参考になったのがJavalobbyの記事。結構後ろの「Implementing the Active Record Pattern」という節に書かれているコードが変態的。
ActiveObjectsはDynamicProxyを使ってインターフェースからオブジェクトを作成します。インターフェースに書いたゲッター・セッターがDBのカラムにマッピングされるのです。そうなってくると、セッターになにかロジックを書きたくても書けません。Hibernateなんかだとユーザーが用意したPOJOに対して、CGLIBを使ってバイトコードをいじって何とかしてますよね。でもActiveObjectsはそんな事しない。どうやってるかというとこんな感じ。
@Implementation(CompanyImpl.class) public interface Company extends Entity { // ... } public class CompanyImpl { private Company company; public CompanyImpl(Company company) { this.company = company; } public void setName(String name) { company.setName(name); name = name.trim(); if (name.length() > 4) { company.setTickerSymbol(name.substring(0, 4).toUpperCase()); } else { company.setTickerSymbol(name.toUpperCase()); } } }
アノーテーションを使って、インターフェースの方に実装をくっつけてるんです。なんてコード…。初めて見た…。
プログラマが書くコードは実装に対してではなく、インターフェースに対してです。この例でいえばCompanyですね。中の動きを見てみるとCompany#setName(String)を呼ぶとCompanyImplに同一シグネチャのメソッドが無いか検索して見つかればそのシグネチャのメソッドを実行するという…。そんなところに流れている雰囲気もActiveRecodeに近いものがあるじゃないですか。面白いっすね。
ところで、ActiveObjectsでMapオブジェクトをDBにマッピングするにはどうすればいいんすかね。MapのEntryクラスを別途クラスにだして…。みたいにちょいと面倒なことをしないといけないんですかね。