staticおじさんとオブジェクトおじさんはお互いに分かり合えるようになるかもしれません。

先日書いたstaticおじさん達に伝えたい、手続き指向とオブジェクト指向の再利用の考え方の違いについて - 達人プログラマーを目指してのエントリに、なんと、みながわけんじ氏ご本人よりコメントを頂きました。もともとは一般のstaticおじさん達(英語ではstatic ojisansという感じ)に向けて書いたのですが、思いがけず、元祖staticおじさん(The static ojisanあるいはMister staticといった感じ)ご本人からのご意見をいただき、本当に嬉しく思います。

オブジェクト指向の再利用性と非オブジェクト指向の関数やサブルーチンとの違いを明確に示していないから
いろいろ理屈を込めても無駄ではないでしょうか?
誰かが作ったクラスを継承して再利用したところで、バグが少なくて、メンテナンス性がいいものができるでしょうか?
そんなものをあてにするより、天才が作ったクラスライブラリやフレームワークを利用して、自分はstaticで作ってしまったほうが、
よっぽど開発効率がよい!というのが今の考え方です。これが今時点で勝つための方法です。
今時、再利用云々いっているのは、十年古い考え方で、私はユーザー企業なので、そういう古臭い会社とは、おつきあいしません。
私が仕事をぜひとも依頼したい人はマイクロソフトのクラスライブラリをよく知っている技術者です。
私の考え方は古くない、むしろコンテンポラリーだと認めていただけないと、たぶん、あなたはビジネスチャンスを潰すでしょう。

いつも通り、なかなかに手厳しいご意見なのですが、ご本人のブログに以下のように書かれていました。

レイヤーつまりソフトウェアアーキテクチャについて正しい認識、センスを持つということで彼に同意です。

いいクラスライブラリ、いいライブラリ関数というレイヤーの上で、いい業務アプリケーションが開発できるというのが素直な考え方です。多くのかたがレイヤーという概念というかセンスを持っていないことに日本のプログラム開発の悲劇がありそうです。レイヤーという概念を把握せずに、クラス分け、つまりプログラムをクラスというサブプログラムに分割してしまうことにより、趣味の悪いメンテナンス性の悪いプログラムができあがってしまう。

私の自論としては、最上位のレイヤーは関数やstatic関数でかなりいけてしまう、その下のレイヤーは現代の開発ツールですとクラスライブラリ化、コンポーネント化されているのでオブジェクト指向となります。だからと言って、業務アプリケーション開発者はオブジェクト指向の勉強をしなくていいということにはなりません。クラスライブラリを使いこなすには、かなりの努力が必要です。

なるほど、以上を読むとオブジェクトおじさんの私としても、かなり共感できるところがありますね。つまり、アプリケーション開発(特に業務アプリケーション開発)の世界において、オブジェクトは部品として利用するけれども、最上位のレイヤーでは手続き的な記述で十分であるということです。staticにするかどうかはともかく、多くの業務システムは上位のアプリケーション層やプレゼンテーション層はステートレスで手続き的な処理を記述することが一般的ですし、並行処理の観点やスケーラビリティの観点からも、それが好ましい場合が実際に少なくないのです。実際、Springなどを使ったJavaのサーバーサイドの開発ではコントローラーやサービスといったクラスはステートレスで、かつシングルトン(インスタンスが一つ)として作成することが一般的であり、実質的にはstaticメソッドで手続きを記述するといったことと大差はありません。また、AccessVBAなどでもデータアクセスやボタン、入力項目などの画面部品はオブジェクトとして再利用しますが、処理は標準モジュールと言語の構文を使って手続き的に記述すればよいことが多いです。
実際、以前にJava EEや.NETはCOBOLやVB6よりも本当に生産性が高いか? - 達人プログラマーを目指してでも書いたのですが、たいしたロジックが不要なデータベースのCRUD処理を中心とした業務システムで、無意味なオブジェクトを多用すればかえって生産性が大きく下がるといったことも事実なのです。
残念なことに、単純にUPDATE文を一つ発行すれば済む処理なのに、SIerの不適切なフレームワークの規約に従う必要から、大量のクラスを作成して何度も値の詰め替えのみ繰り返しながら、ビジネスロジックであるSQL文の実行を行い、結果も逆順に詰め替えてようやく画面に表示するといったようなケースをいろいろな現場で目撃してきました。(侵略的なフレームワーク - 達人プログラマーを目指して)ひどいケースでは本質的なロジックが占める割合が分量からいって10%以下というケースも珍しいことではありません。このような設計は開発工数や保守費用を水増しして売上を増大させるというSIerのメリットにはなっても、決してユーザ企業のメリットになることはありません。もしかしたら、みながわさんもそのようなSIerのダメダメな自称オブジェクト指向フレームワークの被害者の一人なのかもしれないと思いました。
私自身本当にそのような無意味なオブジェクト(お邪魔妖怪アンチパターン)が世の中に氾濫することを心から憎みますし、そういうフレームワークが広く使われているということは本当に問題であると考えています。そうであれば、みながわさんの主張されるようにマイクロソフトなどが提供する使い勝手のよいフレームワーク言語ツールを活用して、生産性を上げるということは(ベンダロックインなどの問題を考えないのであれば)有効な手段であると考えます。
CRUD処理を行うような簡単なアプリケーションに対して、画面を作成するのであれば、

  • フォームを生成する
  • フォームに入力フィールドを追加する
  • フォームに検索グリッドを追加する
  • 検索グリッドにDBのXXXテーブルをバインドする
  • フォームにボタンを配置する

といった非常に簡単な記述(場合によってはGUIツール上のプロパティ設定)により、アプリケーションが完成します。この場合は、フォームやDBグリッドといったようなオブジェクトがプログラム記述の言葉としても使われているのですが、VBAのような上位レベルのプログラムをこのような特化した「言葉」を用いたある種のDSLドメイン特化言語)であると考えることができます。*1GUI部品のクラスライブラリがDSLのモデルを提供し、それを利用する上位層は手続き的なスクリプトやグラフィカルなエディタ上の設定をDSLとして利用すればよいのです。この場合のDSLは一般にデータベースアプリ構築や画面構築に特化した言語であり、汎用のオブジェクト指向言語のように継承したりデザインパターンを使ったりすることは必要ありません。このようなDSLという考え方については、最近以下のような書籍が出版されています。

Domain-Specific Languages (Addison-Wesley Signature Series (Fowler))

Domain-Specific Languages (Addison-Wesley Signature Series (Fowler))

DSLs in Action

DSLs in Action

このように、データベースアプリケーションの開発はマイクロソフトやオラクル、Salesforceといったベンダが最も得意とする領域(ドメイン)なのであり、それらの提供する言語やツールをDSLとして活用することで効率的にアプリケーションを作成するということが可能です。
ただし、ここで見落としてはならない重大な落とし穴があるという点に注意が必要なのです。マイクロソフトが提供する便利な部品はあくまでもCRUD処理のような汎用的なデータベースアプリケーションを開発することを念頭においたしかけのみを提供しているということです。したがって、処理が純粋なデータアクセス処理の範囲であれば非常に有効に機能するのですが、業務処理そのものが複雑なドメインではまったく力不足ということがあるのです。多種類の注文の銘柄を扱ったり、顧客の種類に応じてチェックロジックが微妙に異なったりするといったことを汎用部品はカプセル化してくれません。そのような複雑な業務ロジックを画面部品とDBアクセス部品と手続的なif文やループ文のみで表現した場合、きわめて複雑でメンテナンス不可能なスパゲッティコードになったり、ほんの一部しか異なる部分が無いような大量の関数がいたるところにコピーされてしまうといった状況に陥ってしまうのです。
画面部品はオブジェクトとして実際には複雑な描画ロジックをカプセル化してくれています。だから、わざわざ昔のBASICのように線を引く、色を塗るといった低レベルのルーチンの組み合わせを呼び出さなくても簡単に画面に配置することで再利用できます。同様に、本来は複雑な注文や顧客といったオブジェクトも同様に部品として再利用可能なオブジェクト指向ドメインモデルを作って上位のアプリケーション層やプレゼンテーション層から再利用するという発想だって可能なのです。それが、本ブログで既に何度も紹介している
エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

で書かれているレイヤ化アーキテクチャドメインモデルの構築といった発想につながってきます。なお、注文などのドメインモデルを構築する際にはオブジェクト指向の分析・設計・コーディングが必要なわけですが、そのようなモデルが構築できればその上に必要に応じてDSLを構築することすら可能なのです。そうすることで、画面部品を配置したりするのと同じような気軽さで、業務のオブジェクトを簡易言語やツールで簡単に利用したりすることもできます。そして、この場合も画面とDBとの間にドメイン層が加わってはいるものの、staticおじさんの主張するように上位のプレゼン層やアプリケーション層では継承などのバリバリのオブジェクト指向プログラミングは不要であることが言えます。
結局、staticおじさんとオブジェクトおじさん(DDDおじさん)の違いは、常に与えられたオブジェクトのみを利用してアプリケーションを作ると考えるか、必要に応じて独自の部品を作ろうと考えるかの違いに過ぎないのではないでしょうか。いずれにしても、SIerの変なフレームワークが嫌いということでは共通していますし、レイヤーという考え方を重視するという点、部品の利用を重視する点においても共通しています。(少なくも元祖の)staticおじさんとオブジェクトおじさんは、本来はお互いに分かり合えるようになるかもしれないと思いました。

*1:DSLの実現方法はオブジェクトモデル上に被せた手続き的なファサードに限らず関数型やルール記述言語などの形式が適する場合ももちろん考えられます。実現手段や使い勝手として最適なものを選択すべきという立場です。