モデルの整合性を保ちつつ拡張する
大抵のソフトウェアは一度リリースして終わりではなく,リリース後に顧客(利用ユーザ含む)の要求を取り入れつつ進化させていくことが多い。 現在担当している業務でも,リリースしたサービスをより顧客にとって価値のあるものにするための継続開発を行っている。
継続開発案件での設計,実装は意識してモデルの整合性を保たないと一気に破綻する。拡張性のない,意図が分かりにくい,誰も触りたがらない,バグを量産する魔物となる。これまで何度となく見てきた姿だ。もちろん最初の設計がまったく考えられていない場合は問題外だが。
自分への戒めのためにもモデルの整合性を保ちつつ拡張する事について書いてみる。
変わりゆく要求
まず前提の話。大抵の受託継続開発の場合,はじめに設計した際の前提条件,各モデルの役割,モデルの機能が新たな要求を満たすことは珍しい。顧客の頭の中にはじめから統一されたモデルがあることは期待できず,実際のリリース物を触りつつ,やれたらよいことが要求として生成されていくことは多い。
要求を突っぱねるか変化し続けるか
はじめの設計時点での前提から外れた要求が出てきた場合,開発チームとして取る道は,前提条件が異なっていると要求を突っぱねるか,要求を受け入れ,内部のモデルを変化させていくか。である。
どちらが正しいかは開発チームが置かれている状況によって変わるだろう。強い思想を内在し,その思想を実現するためのプロダクトなのか,あくまで顧客の要望を実現するためのプロダクトなのか。開発チームにはリソースが十分足りているのか,どうしても受注しなければならないのか。状況を表す変数はそれこそ数限りない。
モデルの重要性
変化し続ける道を選んだとする。現在の業務もこの道を選んだ。やりがちなのが,要求を満たすようにのみ実装に手を加えるやり方である。要求の内容によるが,元の意図したモデルの機能とは矛盾するが,ちょっと一つの条件分岐を加えるだけで要求が実現できる場合もある。
だが,この一歩こそがダークサイドへの一歩なのだ。
人間はモデルで世界を認識する。エンジニアも同様である。プログラムそのものを考える時もモデルで考えるはずである。きちんと設計されたオブジェクト指向で書かれているのであれば,オブジェクトは要求の集合体である要件を表現したドメインモデルを自然な形で表現しているはずである。
オブジェクトの自然な動きがずれていくことで,本来のドメインモデルを表現する豊穣なオブジェクトが挙動が読めないただのカオスオブジェクトに成り下がってしまう。言葉と機能の整合性が保てなくなっていく。
受託開発のマネジメントとしては,なるべく少ない工数で直近の今ある要求を満たすソフトウェアを作ることが至上命題なのでなかなかモデルの整合性を保つことにリソースをかけにくいのも実情である。外部仕様としてはモデルの整合性なんてものは関係無いからだ。整合性を保つための努力は短期的に見れば顧客からは単純なコストである。それ故,常にエンジニアは長期的な視点にたった場合のリスクを主張するべきだし,しないと自分の首をしめることになる。正しい言葉を失った世界を生きるのは辛い。
モデルの探求
ある場合には既存のモデルでは変化した要件を表現できなくなる。元々のモデルの言葉が現実の機能を表現できなくなる。これは理解しずらいコードへの一歩である。設計に怠惰なプログラマはそれに目をつもり,ついには言葉と機能のずれを抑えられなくなり,理解不能なコードができてしまう。そのような時は新たな言葉,モデルを探し求めるのである。
常にエンジニアは現在のモデルの正しい姿を追い求め,不断にリファクタリングを進めなければならない。要求は変わりゆくので,それを表現するモデルも変わりゆくからだ。その際に,デザインパターンや計算モデルの知識等が重要になってくる。
おわりに
良いソフトウェアを継続的に開発し続けることは本質的に難しい課題である。少なくとも私はそう考える。
エンジニアとして,価値のある,良いソフトウェアを作るべく,日々格闘していきたい。
君の仕事の質を決めるのはまぎれもない、君自身なんだ。アジャイルサムライより