開発工程で手が止まりがちなのは、設計が必要な工程だ。 具体的には、オブジェクトの階層構造を実装するフェーズになると比較的時間がかかる。
オブジェクトを実装するデータ構造はビジネスロジックのプログラムに細々とまだら状に入り込むので、後から変更しようと思うとけっきょく全体の改修という結論に陥りがちなので、開発プロジェクトのひとつの勝負どころと言える。
データ構造について検討すべき着眼点としては以下のようなものがある。
- 階層構造が適切に表現できているか?属性のうち子オブジェクトとして切り出すべきものはないか?将来的にn個に増える可能性があるならオブジェクトを分けた方が良い
- ステータス遷移は適切に表現できているか?ステータスを親オブジェクトの1属性として実装すると最新1時点のステータスしか管理できないが、それで足りるのか?
- 必須属性を適切に定義できているか?いちど非必須としてサービスインしてしまうとnullが入るため、後もどりしにくい。一方で必須にしてしまうとデータ登録時点で属性を取り揃えておく必要があり、利用の流れ上、それが現実的なのかどうか、というトレードオフも考えておいた方が良い
- 親オブジェクトを削除する際に子オブジェクトも消すべきなのか?
なぜこのような選択に時間がかかるのだろうか?
”できないこと”の定義が最大の難所
設計が本質的に難しいのは、実装する前に「できないこと」を決める必要がある点だと思う。 もちろん「できること」=機能も定義するのだが、実際にやってみると時間がかかるのは仕様から外すことの選択。
前提として「将来サービスがどのように利用されるのか?」という点を見通したうえで、この選択を行う必要がある。 できないことに決めた機能がある時点で必要となった場合、往々にして「作り直した方が早い」ということになりがちだ。
発注サイドは「必要になったらその時点で拡張」という意識であることが多いが、じっさいには拡張できるということは「できないこと」ではないため、トレードオフとして成立していない。
このトレードオフをうまく実行するためには、ビジネスがどのような展開になりうるのかを将棋や囲碁のようにケース別に想像する能力が必要になる。
将来の局面を読む、という要素はシステム開発のもっとも重要なポイントだ。
とくにインターネットビジネスの分野では、支持を集めたときに素早くユーザーを獲得できることがビジネスそのものの存続を分けるため、“その時"には実装できない。 スケールさせなければいけないときに「これからエンジニア採用」と言っていたら勝負は終わってしまう。
サービス立ち上げ前の流行るかどうかも分からない時期に性能やセキュリティを含めた非機能要件を作り込むのはかなりハードだが、一発当てに行こうとしているシステムはそこまでやるべきだと僕は思う。
人は不確実性に著しく弱い
ただ、“将来”、つまり不確実性をともなうものについて考えることが人は著しく不得意だ。
システム開発に限らず、ビジネスの意思決定は不確実性をどう取り扱うかが最重要なのだが、これが難しい。
この点については、行動意思決定論というアカデミックなテーマでも研究されているし、オークションの"勝者の呪い"といったアノマリーのエピソードからだけでもうかがえる。
とくに、できないことを決める、捨てる、という頭の使い方は意識して実践し続けないと身につかない。
98%以上の人は捨てるべきものを決める局面に来たとき、まずその場で答えを出そうとし、その場で答えがでないことに気づき、「これは難しい問題である」が結論だと錯覚し、数分以内に考えることを止める。
「なぜそれが不要なのか?」という点について仮説検証をしていないから、いきなり言われてもできないし、いつまでたってもできるようにならない。
できないことを決めるためには起こりうるメジャーなケースを比較しなければならないのだから、慣れていたとしても一筋縄ではいかない。
データベースを選択したことによる実行リスクとコスト
また技術上の課題については、RDBMS(リレーショナルデータベース管理システム)を正規化したいがために発生している。 RDBMSは不整合のない状態ほど想定どおりに機能できるため、サービス開始後にデータ構造をクリーンに保っておくことが重要だ。
このような、(1)テーブル実装の原理原則と(2)アプリコードの実現したいことのズレは「インピーダンス・ミスマッチ」として知られている。
テーブル実装の原則にしたがうと、階層構造を持つオブジェクトをRDBMSに実装する際に、正規化して複数テーブルに分割する必要が出てくる。 難点は、テーブル間の構造管理などをあらかじめ手動で設定・コーディングしておかなくてはならないこと。
また、データ構造をクリーンに保ちたいがために入力画面が複雑になり、結果的に「作ったは良いが使われない」という事態も起こりがちだ。
“ITの進化"とはよく言われるが、データ構造に関するソフトウェアの問題は基本的には変わっていない。
インターネット以前に各企業の業務システムとして構築されたものがユーザーから見ると難しい感じがするのは、RDBMSの流儀にしたがって設計されたものに入力フォームをつけただけの構造のものが多いからだ。 そして、Webシステムが普及した現時点でも代表的な構造はLAMPであり、要するにそのアーキテクチャはRDBMSの制約を受け続けている(LAMPのMがMySQLというデータベース)。
RDBMSを使う限り開発フェーズのどこかでこの実装を経ることが避けられない。 これは、プロジェクト進行手法としてアジャイルであれば解決する、ということもでもない。開発フェーズを2周繰り返して解決する、ということは倍速で走っているだけで本質的に何かを解決していない可能性がある。
また、脱RDBMSの方向性もそれほど明るくはない。 オブジェクトデータベースやNoSQLを採用するとデータ保存時の問題は回避できるものの、横断検索などの機能に新たな問題が生じる。
けっきょくのところ、ソフトウェア・アーキテクチャの選定・設計は、個別のプロジェクトで一度はトップダウンで解決する必要があり、複雑性が高いだけに人的設計力が求められる、ということが現時点の結論と言える。