読者です 読者をやめる 読者になる 読者になる

業務システムで使うSpring Dynamic Modulesを発表してきました!

Spring OSGi

今回のテーマは「クラウド」という事でしたが、空気を読まずに熊沢先生の「Modularityを考える - 複雑系のアーキテクチャ」への自分の考えを発表してきました。多分に電波を含んでいたので、質問されるとしどろもどろになっていましたが、今回伝えたかった「モジュール化(Modularity)はオブジェクト指向から抽象化を一歩すすめたもの」と言うあたりには納得していただけたようです。
で、結局のところ日本のSIerがやっている業務システムへモジュール化はどうやってやっていくのがいいか、という事に対してうまく答えられなかったわけで、くやしいのでブログに書こう。

モジュールは必要か

自分はシステムが小さいうちからモジュールを意識して作っておく事は保守の面でいいと思ってます。DIの普及により、インターフェースに対してプログラミングを行う作法で実装が行われるようになりました。モジュールを意識して実装を行うと、本来ならば関係のないクラスとメソッドを、同じような処理だから、既にある実装を利用する、という悪しき習慣を改めることができます。例えば

package system.db.utils;
class DBUtils{
  public static boolean isNull(Object obj){
    return obj == null;
  }
}

というDBUtilsがあったとして、UIのレイヤからこのstaticメソッドを呼ぶ、なんてことはモジュールで区分けされていたらできなくなります。DRYの原則ではコピペを悪とされますが、それとこれは話が違います。概念的に違うものを一緒くたに扱う事ですから。もしやるのであれば、

package system.ui.utils;
import system.utils.DBUtils;

public class UIUtils{
  public static boolean isNull(Object obj){
    return ObjectUtils.isNull(obj);
  }
}
package system.utils;
public class ObjectUtils{
  public static boolean isNull(Object obj){
    return obj == null;
  }
}
package system.db.utils;
import system.utils.DBUtils;

public class DBUtils{
  public static boolean isNull(Object obj){
    return ObjectUtils.isNull(obj);
  }
}

というように、両方のクラスから参照できるクラスを用意するのがいいんじゃないでしょうか。モジュール化にはそういう効果があると思うのです。
他にもモジュール化のメリットとして、例を出した方がいいと発表後に思ったのが、バージョンです。リリースしているバイナリが、本当に最新版かどうか、確実な方法を用意していますか?自分はJARなりWARなりの中のメタ情報には必ずビルド日時を入れるようにしています。実行環境にデプロイした時に、確実に動いているものがいつのバージョンのものか、分かるようにしたいからです。
いや、運用でカバーできる、と言う声は絶対あると思うんですが、それって「確実」なんですかね。埋め込まれている情報は、「確実」ですよ。自動的に埋め込まれる訳ですから。(後からメタ情報を入れ替える、という事もなくはないですが、JARなりWARに固めるときに書名情報を埋め込む事もできますよね。そこまではなかなかやらないけども。)

モジュール化のデメリット

モジュール化を行うとオーバーヘッドがかかる部分があります。それは開発時ではなく、パフォーマンスです。モジュールのロードを行う、というフェーズが増えるからです。これは抽象化の弊害とも言えます。だから、オーバーヘッドはそういうものだと思って切り捨てた方がよさそうです。
ところで、モジュール化は結局のところ、システムを機能などの側面から、人が認識しやすい大きさに分割し、わかりやすい名前をつけていくこと、と言いました。じゃ、うまく分割するにはどうしたらいいのか、そこに触れずに終わらせたんですが、この設計が結構大変。例えばオブジェクト指向で設計していてもよくあると思うんですが、Blob(別名GodObject)を作ってしまう事がないでしょうか?リンク先を見ていただくとわかると思うのですが、Blobとはあるクラスが肥大化していくパターンです。肥大化したクラスがあるとテストがしにくく、保守しにくい。そしてそもそも、システムをクラスという単位で分割することで認識しやすくしているのに、肥大化クラスがあるのは、分割がうまく行っていない証拠です。同じように、モジュールは肥大化しやすい訳です。全部入りモジュール。あればそれだけで全部の事ができる、というモジュールを作りたくなりますが、それは性能面でも問題になりますし、使われていない機能に脆弱性があるかもしれない、というセキュリティ面も問題をはらんでいます。
システムが小さな最初のうちに、いくつかのモジュールに分けておき、それを組み合わせることでシステムの稼働に必要な最低限の状態でリリースすることも考えてみるとよいでしょう。

Spring DMのデメリット

Springを使っているアプリケーションをOSGiに載せるのであれば、Spring DMを使わない理由はないです。OSGiで稼働しているアプリケーションにSpring DMを追加した方がよいか、という面でみると、状況によります。Extenderの追加により、システムの複雑性は増します。どんなモジュールを追加しても複雑性は増すんですが、Extenderは他の全てのBundleの内容を走査し、Springの設定ファイルがあれば読み込みます。ロジックには問題ないですが、確実に起動速度に影響します。

今回はいつもやっていたデモは行いませんでした。やっても地味なので。でも見たかった、という声もちらほら。今回は、主張に重点を置きたかったので、ごめんなさいね。と言うわけで、ツッコミ等どうぞよろしくお願いします。