2018年12月27日
ソフトウェア設計が重要である理由
(2018-09-26)by Heikki Hellgren
本記事は、原著者の許諾のもとに翻訳・掲載しております。
新しいプロジェクト始まると、開発者はいきなりプログラミングに飛びつく傾向があります。それもいいでしょう。結局、それが仕事なのですから。でも、時には飛びつく前にブレーキをかけて、ソフトウェア設計から手を付けるのもいい考えかもしれません。
“ホワイトボードを使う長袖のホワイトシャツの男性”(出典: Trent Erwin / Unsplash )
ソフトウェア設計にはいろいろな方法があります。UMLなどのモデリング言語のソフトウェアを利用することもできるし、 テキストを書いて 画像を使うこともでき、あるいはホワイトボードに描くこともできます。ここで大切なのは、ソフトウェアの開発中に設計を保存して再考できることです。設計は多少なりとも改善していかなければなりません。ですから、いつも最初からホワイトボードに描きたいというわけではないのならばデジタルデータで、設計を行うのも良さそうです。データの保存と作成方法は、もちろん、プロジェクトのニーズによって決まります。プロジェクトが小さい場合でしたら、簡単に1枚の紙の上で図や文字にできますが、プロジェクトが大きくなると往々にして進行途上で多くの変更が生じ、ソフトウェア設計にも影響を及ぼします。
正直に言いますが、私もすぐにコードに取りかかる人間で、今まで携わったプロジェクトではフトウェア設計の経験が浅く、詳細に行ったことがありませんでした。更に、開発のピークでソフトウェア設計が縛り付けてくることを何となく嫌悪していました。もちろん、私もホワイトボードやノートに1つのコンポーネントの設計を記したことはありますが、一旦コードが出来てしまうと忘れ去り、全く手を入れませんでした。今の仕事に就いて、ソフトウェア設計をかなり学びました。学ぶことはまだたくさんあるのですが、気付いたことがあるので、ソフトウェア設計の優れたところや重要である理由をシェアしていきます。
モジュラリティ
“オーディオミキサーのコード群”(出典: Steve Harvey / Unsplash )
ソフトウェアは最大で5~10程度のインターフェースを持つ小さな部分に分けられるようにすべきです。このインターフェースの”グループ”をソフトウェアコンポーネントと呼びます。ソフトウェアコンポーネントの中心となる概念は、開発中のソフトウェアの1つの目的を供給するということです。この例を挙げるなら、スーパーマリオブラザーズ3のゲームデータ統計機能でしょう。得点、プレイヤーの残り人数などGUIレンダラが必要とする情報を保つ役割を担います。
モジュラーソフトウェアがあると、移動や更に消去も必要に応じて行うことができ、その上、ソフトウェアコンポーネントごとに複数の開発者間で設計作業を共有することまでできます。モジュラリティがあると、適切なコンポーネントから編集に必要な情報を得やすくなるのでメンテナンス性も高まります。また、コンポーネント単位でテストケースを分けるように、ソースコードの名前空間や構造の根拠にもなります。
メンテナンス性
“グレーのレンチ”(出典: Mikael Kristenson / Unsplash
ソフトウェア設計が優れていると、ソフトウェアのメンテナンスが簡単です。設計を見れば修正するバグの量や新しい機能の導入によって現在のコードベースにどれほど影響があるかがすぐに分かります。優れたソフトウェア設計は幾つものソフトウェアコンポーネントとそのインターフェース間の相互作用も表すので、変更を要するコンポーネントが与える別のコンポーネント内のコード変更といった影響も明らかにします。ソフトウェア設計を持たない場合、特に古いコードベースの開発は、非常に手間がかかり、想定外のバグを多々生み出します。
ソフトウェア設計をやってみると、実際には使わず、顧客も求めていない多くの無駄なインターフェースに気付きました。こういったものはコード上でも簡単に見つけられるのですが、通常は誰も余計な機能に注意を払いません。余計な機能は余計なメンテナンス、テスト、開発を生みます。誰もそんなものは望みません。ですから、行うべきはシンプルさを保ち、ニーズを満たし、それ以上は何もしないことです。
パフォーマンス
優れたソフトウェア設計、特に高い粒度で設計されている場合は、ソフトウェアのパフォーマンスでボトルネックとなる部分を正確に示すのに使えます。つまり設計は、システム内部の振る舞いを分かるようにするべきであり、スレッド、データベース、コネクションなど、パフォーマンスに影響を与えうるリソースが、どのようにシステムで使用されているかを示すべきです。ボトルネックは、デバッグやロギング機能を使ってソースコードから割り出すのが手っ取り早い場合もありますが、ソフトウェア設計の1つのイメージで示せる場合もあります。
ソフトウェアを細部まで設計するのは良いことですが、やりすぎは禁物です。全てのループや条件を設計する必要はありません。そんなことをすれば、設計と続く開発との間を反復することになり、設計の保守性は恐ろしいほど低下します。しかも、開発者に対しても、何らかの形でソフトウェア設計を目にする顧客に対しても、新たな価値を生むものではありません。
ポータビリティ
サードパーティのライブラリなど、他のソフトウェアモジュールへの依存性を設計に盛り込むと、ソフトウェアを別の環境へ移動することが格段に簡単になります。これを1つの場所に文書化することができれば、別の環境を使う場合に必要な変更を見つけるのが非常に容易になります。
それでも、バージョンをアップデートしたり基本的なライブラリを変更したりすると全体的な設計の見直しが必要となるため、サードパーティのソフトウェアに対する全ての関数呼び出しを設計することは避けたいと思うでしょう。その場合でも、皆がソフトウェアの振る舞いを理解するために必要な対策は忘れずに行ってください。
ユーザビリティ
ソフトウェア設計から顧客向けの設計文書を作成するというのは名案です。顧客が、使おうとしているソフトウェアの振る舞い方について概要を知ることができるからです。設計が優れていると、ゼロの状態からソフトウェアをプログラミングすることが非常に簡単になるため、公開インターフェースだけを提供し、内部設計を文書から省いてもいいかもしれません。
ソフトウェア設計は、新人にとっての素晴らしい出発点ともなります。全てのソースファイルに目を通さなくても、新人が最初に必要とする全情報がソフトウェア設計に含まれているからです。
トラッカビリティ
通常、プロジェクトには顧客か内部ソースから提示される要件があります。優れた設計は要件を追跡します。そして、ソフトウェアからの要求を網羅し、正しく理解されていることを設計レベルで示します。これにより、どの要求がどこで満たされているかを顧客が実際に確認できるようになるため、提供される設計文書の価値は更に高まります。設計をソースコードと統合させるために、設計、要件、ソースコードを何かしらの方法で結び付けることが非常に強く推奨されます。
デプロイメント
設計は、どんなソフトウェア要素成果物があり、それらをデプロイメントの際にどこに置くべきか、という情報も提示するべきです。顧客は、ライブラリ、実行ファイルなど、ソフトウェアに関するあらゆる要素成果物の場所を知る必要があるので、この情報は統合化と同じように非常に重要です。これがあれば、最新の納品物でソフトウェアに不可欠なパーツが欠けていても、設計書を見るだけで簡単に見つけられるようになります。
何が必要か?
“拳を突き合わせる人々”出典: rawpixel / Unsplash
ここまでソフトウェア設計が重要である理由をいくつか説明してきましたが、次は何が必要かを考えましょう。優れたソフトウェア設計には、訓練とソフトウェアに携わるチーム全員の献身的な姿勢が必要です。時には設計とソフトウェアを一致させるために無数の反復を要求されます。たとえあなたがコンピュータ時代の申し子だとしても、コーディングを始める前に、全ての事象に気づくことはできないでしょう。しかし、それは問題ではありません。反復は設計と同じように堅牢なプログラムを作ります。時間や労力が必要ですが最終的には報われ、ソフトウェアのあらゆるリスクを軽減します。信じられないと思うのでしたら、次のソフトウェアプロジェクトでぜひ試してください。
株式会社リクルート プロダクト統括本部 プロダクト開発統括室 グループマネジャー 株式会社ニジボックス デベロップメント室 室長 Node.js 日本ユーザーグループ代表
- Twitter: @yosuke_furukawa
- Github: yosuke-furukawa