侵略的なフレームワーク

SpringやSeasar2などの軽量なフレームワークが登場し、POJO、DI、AOPという考え方が今ではすっかり浸透してきているのかと思いきや、ぜんぜんそんなことはないみたいです。客先でも(主に社内での)実績最優先という考え方から、最近のOSSフレームワークには手を出さず、日本の大手SIer謹製のフレームワークを採用したり、自社フレームワークを採用したりするケースが意外に多いですね。そういう場合によくありがちなのが、プログラマーのスキルによらずに作れるようにするという目的から、無意味な規約を強制するケースです。
実際、今日ある国産ベンダーのフレームワークを採用したシステムの設計書に記載されているクラス一覧を見ていて無駄がいかに多いかということに驚いてしまいました。たとえば、ユーザー一覧を検索するという処理でSeamならエンティティクラス、画面、JPQLがあれば実装完了なのですが、そのフレームワークの規約に従うと

  • JSPファイル
  • UserListView(ビュークラス)
  • UserListHB(ヘルパーBeanクラス)
  • UserSC(サービスコントローラー)
  • UserSR(サービス呼び出し結果)
  • UserListEv(イベント)
  • UserListEL(イベントリスナー)
  • UserListER(イベント結果)
  • UserMO(DTO
  • UserDAO(DAO実装)
  • UserDAOIF(DAOインターフェース)

のような感じで、あきれる程大量のクラスを作成する必要があるとみえて、その詳細設計書には同じような名前の一連のクラスがぎっしりと記述されていました。恐ろしいほどのパラレル継承といいますか、一機能追加するだけでこれほど大量のクラスを記述しなくてはならないのです。(おまけに、追加作業として各クラスにつき大量のXML登録も必要なようですし、クラス設計書とか単体テスト仕様書などを含めると相当な工数になると思われます。)さらに、クラスは無駄にたくさん存在するのですが、オブジェクト指向的な要素はまったく感じられず、モジュールなど再利用可能な凝集性の高いコンポーネントの単位も一切存在しません。どこを切っても金太郎飴のように同じようなセットのクラスがたくさん作られており、一見統制が取れていて美しいという錯覚さえ覚えてしまうほどですが、実装されているユースケースに対してはあまりにも非効率な設計であると言わざるを得ません。これではVB6時代のプログラミングモデルの方がはるかに生産性が高かったとさえ言えるかもしれません。
このような設計はEJB2.1時代とかStruts以前の時代にはともかく、いまだに採用されることが結構あるのですね。こうした設計は頭を使わないような配管コードの実装が大半なので、人月あたりのクラス数とかステップ数で生産性を出すとものすごく生産性が高いということになるし、がんばって仕事した気分にはなるかもしれませんが、意味のある業務ロジックの密度が非常に低いので、実際のユースケースを実現するという観点からはきわめて効率が悪いのです。その上、機能追加やバグ対応などの保守性も当然低くなります。こういうフレームワークはある意味でプログラマーの仕事を作ってくれていると言えますが、無駄な公共事業で道路を掘り起こしているようなものですから、こういう設計に疑問を感じず規約通りコーディングするならIT土方と呼ばれても文句が言えません。最低でも自動生成するとか、もっとよいのはAOPなどの技術でコンパイル時か実行時にこうした無駄な配管ロジックを生成してしまうのがまともなプログラマーが考えるべきことでしょう。以前、私の担当した案件で、政治的理由からこうした侵略的なフレームワークの採用が決まっていたプロジェクトでは、規約通りのクラス群を一組だけ作成しておき、Springの動的Proxy生成機能を使ってパラメーターで渡したメタ情報を使って実際のPOJOサービスクラスをリフレクション起動させるようにハッキングして、何とかまともな開発生産性をキープしたというケースがありました。トランザクションとかリモーティングで使われている手法と同じで、サービス呼び出しクライアントもサービス側もPOJOのみ意識すればよくして、その面倒なフレームワークを完全に隠蔽しました。結果として、ユースケース数に対してあまりにもステップ数が少なく生産性が低いのではないかと指摘されましたが、実態としてはもちろん逆なのは明らかです。