プログラミングと設計は本来切り離せないものなのでは

最近はアーキテクトという役割で客先に常駐し、フレームワークの選定をしたり、事前に共通部品を設計したりする役割を担う仕事を引き受けることが結構あります。そこで運よくお客様のマネージャーがオブジェクト指向開発の経験が十分にある方だと、IDEなどの開発環境やインターネット接続環境を当然のように用意してくれるので最初から仕事がスムーズにできるのですが、そうでないとMS Officeしか入っていないロースペックのノートPCを渡されて、要件定義フェーズの期間中、フレームワークの設計をお願いしますとか、私としてはちょっと首をかしげてしまうような困ったことを言われてしまう場合があります。開発フェーズが始まる半年後まではコーディングは基本的に不要という考え方です。アプリケーションのアーキテクトという役割では少なくともコーディング規約を考えたり、ツールやフレームワークの選定をしたりする必要がありますし、プロジェクト全体をウォーターフォールで進めたいのであれば、なお一層のこと事前検証の意味で、アーキテクトがコーディング作業も含めてアプリケーションの開発方法やパターンを明確化しておくことが重要なはずなのですが。
そのPMにそのことを話したら「コーディングが好きな人もいますが、いきなりコーディングできるようなプログラムはたいした思慮が入っていない設計であるからあまり信頼できないし、じっくり時間をかけて事前設計してください」と言われてしまいました。また、そういう人は作業の手戻りということを極端に気にしますから、要件定義できていないのにコードを書いて後から捨てるというのはもったいないと考える傾向が強いです。(なぜか、1年とか長い時間をかけてExcelの表とかUMLの図などの大量の分析資料を量産することは無駄なコストとは考えない。)そういう人の存在を老害だと一言で片付る議論もあるようですが(SI業界の老害が若手と下請けを蝕む理由 - yvsu pron. yas)、30代の若手のマネージャーでもそういう発想をする人はたくさんいるし、50代のベテランエンジニアでコーディングの重要性を理解してくれる人も世の中にはいるので、必ずしも年齢は関係ないと思います。運悪くそういう環境で働くことになったら、「変化の触媒たれ」という達人プログラマーの心得でもって徐々に時間をかけて考え方を変革していってもらうよう努めています。多くの場合その人がプログラミングという行為を設計と結びつけて考えられないのは、単にその人の経験不足、知識不足ということが多く、リファクタリングなどでいかに無駄なコーディングが減らせるか、生産性が向上するかということを実演して見せれば簡単に現代的な開発におけるコーディングと設計のつながりを正しく理解してもらえるようになることも多いと思います。
現在のようなオブジェクト指向の開発環境が一般化する前の言語では、データ構造を設計し、それに対する処理の流れを設計してしまえばよかったですし、いきなりアセンブリCOBOLでコードを書き出さなくても、そういった設計は事前に設計図上で時間をかけて検討するということは可能であり、コンパイルに膨大な手間と時間がかかっていた時代であれば理にかなっている行為であったと思います。しかし、少なくとも現代的な開発環境上でJavaなどのオブジェクト指向言語を使って開発することを考えた場合、それらの伝統的な設計の他に

  • インターフェースの設計
  • アノテーション(注釈)などのコード中のメタデータの使い方の検討
  • パッケージなどのモジュール分割
  • 適切な数のレイヤーの分割
  • デザインパターンの適用
  • ジェネリクス(総称型)などの型の設計
  • jarファイル分割などの物理的なモジュールの設計
  • eclipseなどのプロジェクト分割
  • mavenやant+ivyを使ったビルドシステム構築
  • 単体試験方式の確立
  • OSSライブラリーなどの依存関係の調査
  • 通化可能なアスペクトの設計

などなど、IDEを起動してあらかじめサンプルを作りながら検証しないと本質が理解できない要素があまりにも多く存在します。Javaのプログラムは、単純にifやforループの集まりとして捉えることはできないということです。実際、Seamなどの便利なフレームワークを活用すれば、型変換なども含めて大部分はロジックを書かなくても宣言的に再利用できてしまいますし、アーキテクチャーの設計といった場合、個別のロジックに絡まない以上のような要素の設計の方がむしろ重要になってきます。これらはUMLなどを使ってある程度コーディングなしで設計できる部分はあるとは言え、アノテーションなどの言語固有の設計要素や開発ツールのくせを考慮した実装方式は実際にコーディングして慎重に検証しながら考える以外に効率的に設計することは難しいです。このような要素をあらかじめ開発フェーズまでに明確にしておく、つまり、生産性の高いプログラミングモデルを決めておくということは、経験上開発プロジェクトの成功の上に欠かせない作業項目であると考えます。まずはコード上でじっくり設計を考えた後で、説明資料として後から必要に応じて要点をUMLで文書化するという流れの方が作業手順としてしっくり来ることが私の経験上ほとんどです。コードこそが設計の本質をもっとも正確かつ簡潔に表現できる手段なのであり、UMLはそのある側面を捉えやすくする方便としての一表現に過ぎないなどと言うと怒られてしまうでしょうか?(間違えないでいただきたいですが、EAとかSOAなどの粒度のアーキテクチャーではなくて、単一のアプリケーションのアーキテクチャーを設計することをここでは念頭に置いています。もちろん、プログラミングモデルの検討以外に、セキュリティや性能、保守性などアーキテクトとして検討すべきことは他にも山ほど存在するという前提で。)
あと、複雑な業務領域のシステムでは、DDD(Domain-Driven Design: Tackling Complexity in the Heart of Software)を使ったドメインモデリングが有効ですが、JPAなど採用するデータアクセスフレームワークの特性に応じて設計のフィージビリティーを確認するには、早期にエンティティクラスを作成しながらモデルを洗練させることが有効です。また、JSFなど複雑なプレゼンテーションフレームワークを利用するなら、あらかじめ画面紙芝居を開発して、そのフレームワークで画面遷移などが簡単に実現できることを実際に検証しながら画面設計をするべきです。
コーディングなどは単価の低いプログラマーの仕事であり、アーキテクトにやらせるのはもったいないなどと考えて、開発フェーズまでコーディングしないなどというやり方をしていては、後々設計の足りていない箇所がたくさん見つかり、結局個々のプログラマーが場当たり的に設計しだすのでアーキテクチャーは余計に混乱することになると思います。アジャイル開発を採用せず、ウォーターフォールで開発するのであれば、なお一層のことアーキテクトチームや事前開発チームのような体制を作って、要件定義と並行して早期にプログラミングをしながら設計を固めるというのが大事だと思います。(RUPの推敲フェーズのようなものを取り入れるべき)
さらに、付け加えるとこのような事前開発は、技術リスクの軽減効果だけでなく、開発メンバーのスキルアップという教育面での効果も高いです。事前開発を通してツールの使い方やフレームワークの使い方をそのプロジェクトの文脈で学ぶことができるのですから非常に効果的な教育ができます。
SEとPG、どっちが頭がいい?(2):下流から見たIT業界:エンジニアライフでは、「PGもSEも頭が空っぽ」と結論していますが、多くのプロジェクトでは残念ながらそのとおりだと認めざるを得ないと思います。面倒だけれど根気さえあれば誰でもできるようなExcelの項目一覧表や画面定義書の作成に終始しているSEがいる一方で、規約に従ってそれをそのままコードに落とす(しかない)PGがいるということで。Excel表がその場合上流と下流の間の契約というかインターフェースを決めているのですが、そのせいでSEもPGもその存在が足かせとなってCOBOLやVB5時代の設計手法しか使えず、特にオブジェクト指向技術を使った開発効率や再利用性、保守性の向上をまったくといっていい程達成できないようになっていると思います。せいぜい可能なのはExcelの達人になってマクロを思いっきり工夫するとか、SQLのチューニングの名人になるとか、そういった分野でしか技術力を生かす余地がないのです。
元請と下請をコーディング有り無しの観点から上流・下流と分けるのは、Java EEや.NETのようなオブジェクト指向を前提とした開発環境ではどう考えても絶対に不適切だと思います。アウトソースするとしても、コアドメインと非コアドメインなど業務領域で分けるなどの工夫ができないものでしょうか。たとえば、金融に特化した会社であれば、トレーディングなどコア部分の開発はコーディングを含めて自社開発し、汎用のパッケージの流用部分とか画面周りや認証などの一般的な知識があれば開発できる領域は外部の専門の会社にアウトソースする(オフショアを含む)などが本来はできてしかるべきだと思います。
ゼネコン体質など日本のIT業界固有の商習慣から難しいところもあるかとは思いますが、要件定義フェーズ中に一切プログラミングしないという厳格なウォーターフォールを採用しているプロジェクトでは、この点是非なんとか改善してもらいたいです。
このエントリーをはてなブックマークに追加