2.12 ソフトウェアのモデルと手法
概要と動機
ソフトウェアモデルとは、特定の問いに答えるために作られる、システムの意図的な単純化です。手法とは、ソフトウェアを作り出す規律ある方法であり、その途中で使うモデルを含みます。両者は合わせて、ソフトウェアエンジニアリング知識体系(SWEBOK)の一つの知識領域を成します。作る前、作る間、作った後にシステムについて推論するために使う、頭の中の道具だからです。UML(統一モデリング言語)のクラス図、実体関連図(ERD)、状態機械、形式仕様、使い捨てのプロトタイプは、すべてモデルです。ウォーターフォール、プロトタイピング、形式開発、アジャイルは、すべて手法です。
そもそもなぜモデルを気にするのでしょうか。人間のワーキングメモリは小さく、ソフトウェアシステムは大きいからです。十万行のシステムを頭に収められる人はいないので、一度に一つの側面、つまりデータ、制御フロー、状態、相互作用を示す絵を描き、抽象を書きます。モデルはコードに忠実であることを意図されておらず、決定に適していることを意図されています。良いモデルは、何かを決めるのに必要なものを正確に示し、それ以外のすべてを隠します。
大きなチームでは、本当の賭け金は調整とコミュニケーションです。何百人ものエンジニア、アーキテクト、アナリスト、監査人が一つのシステムで働くとき、共有されたモデルは、設計、要求、リスクを交渉する共通の土台になります。だから、モデリングを、果たすべき仕事を持つ道具として考えてください。モデルが、それが防ぐ間違いより安いときに、見返りがあります。それ自体のために描いたり、古くなってもずっと保持したり、それが仕えるはずだった決定を超えて詳細化したりすると、無駄になります。モデリングは、ソフトウェア要求(2.8章)、ソフトウェア設計原則(2.2章)、アーキテクチャとC4やarc42のようなその記法(3.1章)、アジャイルな働き方(10.7章)に密接につながります。
主要原則
- すべてのモデルには目的があります。モデルが情報を与える決定を名指しできないなら、それを描いてはいけません。
- 抽象化はモデリングの中核的な行為です。目的に関わるものを含め、残りは省きます。
- モデルの内部でもモデル間でも一貫性が重要です。矛盾するモデルは、ないよりも悪いものです。
- モデルはまずコミュニケーションの成果物です。読み手が、その記法と詳細度を決めます。
- 問いに答えられる最も軽いモデルを好みます。詳細化には持ち越しコストがあります。
- モデルは、その分析の分だけ良いものになります。確認されていないモデルは、テストされていない仮定です。
- 問題の不確実性、リスク、失敗の結果に合わせて手法を選びます。
推奨事項
抽象化、目的、一貫性をもってモデル化する
すべてのモデルを、その目的と読み手を名指しすることから始めます。それから、その目的に向けて容赦なく抽象化します。競合状態を解決するためのシーケンス図は、すべてのフィールドではなく、タイミングとメッセージを示すべきです。モデルを互いに一貫させ、ERDのエンティティ、クラス図のクラス、要求の名詞がすべて一致するようにし、現実とも一貫させます。それは、システムが先へ進んだらモデルを更新または削除することを意味します。人々が信頼する古いモデルは危険です。全員が無視する古いモデルは、なお注意を費やす無駄です。
問いに合わせて、構造モデルか振る舞いモデルを選ぶ
システムが何でできていて、部品がどう関係するかを示すには構造モデルを使います。クラス図、コンポーネント図、データ構造のための実体関連図。システムが時間とともに何をするかを示すには、振る舞いモデルを使います。意味のあるライフサイクルを持つオブジェクトのための状態機械、コンポーネント間の相互作用のためのシーケンス図、ワークフローやビジネスプロセスのためのアクティビティ図。目の前の決定を露わにする記法を一つ選びます。ほとんどのシステムに必要なのは、あらゆるものにUMLのカタログ全体を適用するのではなく、選択的に描かれる少数の図の種類だけです。
モデルを描くだけでなく、分析する
モデルは、描くことだけでなく分析によって価値を稼ぎます。状態機械について、到達不能な状態、欠けた遷移、デッドロックを確認します。ERDについて、正規化の問題と孤立した関係を確認します。シーケンス図を要求に照らしてたどり、欠けたエラーの経路を見つけます。何が間違っているかを見つけられるドメインの専門家とモデルをレビューします。そして失敗のコストが高い所では、目で確かめるのではなく、ツールに支えられた分析(モデル検査器、一貫性チェッカー、シミュレーション)に手を伸ばします。
ヒューリスティックな手法を既定として適用する
ほとんどのソフトウェアは、ヒューリスティックな手法で作られます。経験に基づく反復的なアプローチで、モデルを非公式に使い、証明ではなく期待に照らして結果を判断します。ほとんどのビジネスシステムや政府のシステムにとって、それはまさに正しいことです。要求は進化し、欠陥は通常、回復可能だからです。ヒューリスティックな手法はアジャイル(10.7章)と自然に組み合わさります。チームを揃えるのに十分なだけモデル化し、それから作って学びます。
形式手法は結果の重い中核のために取っておく
形式手法は、仕様を数学で表現し、証明や網羅的なモデル検査といった検証を使って性質を確立します。本物のスキルと時間がかかり、失敗が壊滅的または不可逆である場所でこそ見返りがあります。安全が重要な制御、暗号プロトコル、金融の決済の中核など。システム全体ではなく、小さな重要な中核に適用します。そして、完全な証明がなくても、形式仕様だけで、正確であることを強いるだけで価値を加えることが多い点に注意してください。
プロトタイピングで不確実性を取り除く
要求や実現可能性が不明確なときは、学ぶためにプロトタイプを作り、それから意図して、進化させるか捨てるかを決めます。使い捨てのプロトタイプは問いを安く探り、その後削除されます。進化的なプロトタイプは製品になり、本番の水準で作られなければなりません。典型的な失敗は、使い捨てのプロトタイプが偶然、本番に滑り込むことです。だから作る前に、プロトタイプの種類を名指ししてください。
流行ではなくリスクに手法を合わせる
問題の不確実性と失敗の結果で手法を選びます。高い不確実性は、プロトタイピングとアジャイルの反復を好みます。高い結果は、形式分析と厳格な検証を好みます。両方を持つシステムには、それ以外はアジャイルの枠の中に、重要な形式的中核が必要です。何をするにせよ、手法が権威あるものだから、あるいはベンダーが売っているからという理由で採用してはいけません。
トレードオフ: 長所と短所
| モデルまたは手法 | うまく適用された場合 | 失敗モード |
|---|---|---|
| 構造モデル(UML、ERD) | 部品とデータの共有された絵 | 図の乱立。コードからの乖離 |
| 振る舞いモデル(状態、シーケンス、アクティビティ) | タイミング、状態、エッジケースを露わにする | 誰も読まない詳細すぎる図 |
| ヒューリスティックな手法 | 速く、柔軟で、ほとんどのシステムに合う | 規律がない。隠れた仮定 |
| 形式手法 | 重要な中核に対する証明可能な性質 | 高コスト。システム全体への誤った適用 |
| プロトタイピング | 安い学び。リスクを早期に取り除く | 使い捨てのコードが本番に昇格される |
| アジャイル手法 | 変わる要求に適応する | 難しい問題に必要なモデリングを飛ばす |
繰り返される緊張は、厳密さと速度の間にあります。モデリングが少なすぎると、隠れた仮定を本番に出荷します。多すぎると、決定に役立たない図に労力を燃やし、コードが変わった瞬間に腐ります。これを直す決まった量はなく、釣り合いのルールだけがあります。モデルや手法への投資を、それが解決する不確実性と、決定を誤ったときのコストに比例させます。決済エンジンとマーケティングのマイクロサイトは、異なる扱いに値します。
チームで議論すべき問い
私たちはモデルを分析していますか。それとも、描いて先に進むだけですか。 モデルは、存在することではなく分析によって価値を稼ぎます。到達不能な状態や欠けた遷移を確認したことのない状態機械は、図に仕立て上げられた、テストされていない仮定です。大きなチームでは、ここに本物の欠陥が潜んでいます。もっともらしく見える絵は、誰もそれを要求に照らしてたどって、欠けたエラーの経路や孤立した関係を見つけていないまさにそのときに、信頼されるからです。最も重要な振る舞いモデルを会議に持ち込み、壊してみてください。どの遷移が未定義か、どの状態に出口がないか、どのシーケンスにタイムアウトがないか。失敗のコストが高い所では、答えは、目で確かめるのではなく、ツールに支えられた分析(モデル検査器、一貫性チェッカー、シミュレーション)に向かわせるはずです。重要な中核をモデル化するそもそもの理由は、欠陥を本番ではなくホワイトボードで見つけるためだからです。
二つのモデルが食い違うとき、どちらが勝ち、その矛盾に気づくのは誰ですか。 一貫性はモデルの内部でもモデル間でも重要で、矛盾するモデルは、人々が両方に基づいて行動するので、ないよりも悪いものです。大きなシステムでは、データモデルのエンティティ、設計のクラス、要求の名詞が、異なるチームが異なる成果物を更新するにつれて静かに乖離し、最初の兆候はしばしば、二つのコンポーネントがあるものが何かについて食い違った本番のバグです。例を持ち込んでください。核となる概念を選び、ERD、コード、要求が、その形とライフサイクルについて実際に一致しているか確認します。していなければ、どの成果物が権威を持ち、他を揃えておく責任が誰にあるかを決め、古いモデルがチームに嘘をつき続けるのを許すより、モデルを削除する意思を持ってください。
システムのどの中核が、間違っていれば本物のお金を失ったり誰かを傷つけたりし、それはふさわしい厳密さを得ていますか。 本章の中心的な動きは、手法をリスクに合わせることです。回復可能な大多数にはヒューリスティックでアジャイルな手法、小さな結果の重い中核には形式仕様と検証、本当に不確実なものには安いプロトタイピング。失敗モードは対称的で、どちらも高価です。マーケティングのマイクロサイトに形式手法を適用すればお金を燃やし、決済エンジンや適格性のルールセットを通常のアジャイルの仕事として扱えば、壊滅的で不可逆な欠陥を招きます。システムのマップを持ち込み、誤りが壊滅的か回復可能か、要求が確実か未知かに印を付けてください。答えは、モデリングへの投資を、お金と曖昧さのある所に集中させ、他のすべての場所では明示的に控えるべきで、重要な形式的中核が、それ以外はアジャイルの枠の中に、どちらの手法も他方の領域に漏れずに収まるようにします。
コードを書く前にどれだけモデリングし、その量は目の前の不確実性で変わりますか。 大きな事前設計も、設計をまったくしないことも失敗モードで、適切な量はその間にあり、モデルが実際にどれだけの不確実性を取り除くかで決まります。大きなチームでは、圧力は両方向に働きます。ガバナンスのプロセスは、コードの前に完全な図の集合を求め、最も少ない情報でなされた決定を固定するかもしれず、デリバリーの圧力は、高くつくエッジケースを捉えたはずの一つの状態機械をチームに飛ばさせるかもしれません。直近の二つのプロジェクトを持ち込み、作ったモデルを、本物の決定に情報を与えたものと、テンプレートが求めたから描かれただけのものに分けてください。フェーズゲートや承認委員会が文書を前もって義務づけることの多い企業や政府のプログラムでは、固定された成果物のリストではなく、リスクに追随するモデリングのために論じる準備をして、決済の中核が厳密さを得て、社内のレポートツールが誰も読まない図に溺れないようにします。
共有の記法とモデルの単一の置き場所に合意していますか。それとも、どのチームも独自のものを発明していますか。 モデルはまずコミュニケーションの成果物で、あるチームのツールで描かれた状態機械が、それを引き継ぐチームに読まれず、見つけられず、信頼されないとき、その価値は崩れます。何百人ものエンジニアにとって、相反する考慮は本物です。義務づけられた記法とリポジトリは、一貫性と見つけやすさを買いますが、学習コストも課し、撮影したホワイトボードで足りる所で、重いツールへと人々を向かわせえます。モデルが実際にどこにあったか(ウィキ、図のツール、スライド、誰かのノートPC)の例を持ち込み、六か月後に誰がそれを見つけて理解できるかを問ってください。企業や規制された設定では、監査の角度がこれを鋭くします。現在のデータモデルを見つけたり、決定を文書化された状態機械までたどったりできない監査人は、システムを文書化されていないものとして扱うので、小さな共有の記法と持続的な置き場所に合意し、結果が低い所ではどこでも、儀式より軽い記録を受け入れます。
プロトタイプを作る前に、それが使い捨てか進化的かを意図して決め、その選択を守っていますか。 典型的で高価な失敗は、デモ映えして誰も前もって種類を名指ししなかったために、使い捨てのプロトタイプが静かに本番に滑り込むことです。緊張は本物です。使い捨てのプロトタイプは最も安い学びを買い、削除されるべきで、進化的なプロトタイプは製品になり、最初の一行から本番の水準で作られなければならず、両者を混同すると、手戻りを無駄にするか、設計されたことのない役割に脆いコードを出荷します。最近のプロトタイプを持ち込み、作る前に何が決められたか、昇格または破棄する権限が誰にあったか、その決定がデリバリーの圧力を生き延びたかを問ってください。市民向けのシステムが透明性と信頼性の義務を負う政府やその他の説明責任のある設定では、偶然の昇格を統制の失敗として扱います。プロトタイプの運命を前もって決め、成功した使い捨てを破棄することを、避けるべき無駄ではなく、祝うべき成果にします。
セクター別の視点
スタートアップ。 ホワイトボードでモデル化し、写真を撮り、先へ進みます。最も乏しい資源はエンジニアリングの注意なので、モデルが、それが防ぐ間違いより安いときにだけ手に取ってください。来月ピボットするかもしれない製品のためのUMLのカタログ全体ではなく、課金のエッジケースをコーディングする前のサブスクリプションの状態機械。ヒューリスティックでアジャイルのままにし、形式手法は完全に対象外とし、意識的にそう決めない限り、すべてのプロトタイプを使い捨てとして扱います。
小規模事業者。 形式的なモデリングが仕事の人はおそらくいないので、自前のモデリングの実践を立ち上げるのではなく、買うツールとフレームワークにすでに組み込まれたモデルに頼ってください。描く少数のモデルは具体的な決定の周りに枠づけます。どの顧客データを保持しているかを合意するための単純なデータモデルのスケッチ、壊れると顧客を失う唯一のワークフローの状態図。自分で作って文書化するより、実証されたデータモデルを持つ買った製品を好み、描くものは、一人で保守できるほど軽く保ちます。
大企業。 中核の問題は多数のチームにわたる調整なので、共有のモデルが共通の土台になります。合意されたデータモデル、一貫した記法、ERD、C4の図、状態機械が見つけられ信頼される置き場所。小さな記法を標準化して一貫性を徹底し、要求、設計、データベースのエンティティがチーム間で乖離しないようにします。形式仕様とモデル検査は、結果の重い中核(決済、照合、アクセス制御)のために取っておき、それが要求する専門スキルに資金を出し、文書化された各モデルから、それが正当化した決定までの監査の跡を保ちます。
政府。 法律で定められたルールは、制定法までたどれなければならず、そこで形式仕様がそのコストに見合います。適格性や査定のロジックを正確に規定し、主要な性質を検証し、監査人があらゆる結果を、それを生んだルールまでたどれるようにします。調達は独自の重みを加えます。文書とモデルはしばしば契約上の成果物なので、チェックリストを満たすためだけに作られたのではなく、本当に決定を担うモデルがどれかを合意してください。重要なシステムがどう動くかの平易な説明を公開し、本番のビルドにコミットする前に、市民向けの受付を本物のユーザーでテストするために、使い捨てのプロトタイピングを使います。
事例
スタートアップ。 サブスクリプション課金の製品を作る小さなスタートアップは、コードを書く前に、サブスクリプションのライフサイクル(トライアル、有効、支払い遅延、解約、再開)を、ホワイトボードの状態機械としてスケッチします。図をたどって、支払い遅延のアカウントの支払いがついに通ったときに何が起こるかを定義していないことに気づきます。それは、本物の顧客を宙ぶらりんにしたであろうエッジケースです。その5分のモデルが本番の頭痛を省き、彼らは重い図のツールを保守する代わりに、写真を撮ります。それ以外のあらゆる所ではアジャイルのまま、揃えるのに十分なだけモデル化します。彼らの規模では欠陥は回復可能で、形式手法は純粋なコストだからです。
大企業。 グローバルな銀行が新しい決済プラットフォームを構築します。チームは、実体関連図を使って、口座、元帳、メッセージングのチームにわたる共有のデータモデルに合意し、C4の図(3.1章)でサービスがどう組み合わさるかを示します。トランザクションのライフサイクル(保留、清算済み、決済済み、取消、係争)を明示的な状態機械としてモデル化し、分析によって、部分的な取消の遷移が欠けていることが明らかになります。そのギャップは、本番ではなくホワイトボードで直されます。シーケンス図が決済のフローを要求(2.8章)に照らしてたどり、欠けたタイムアウトとリトライの経路を表面化します。日々のデリバリーはアジャイルですが、誤りが本物のお金の損失を意味する中核の照合アルゴリズムは、形式仕様を与えられ、実装の前にモデル検査されます。モデリングはお金と曖昧さのある所に集中し、他のあらゆる所では軽く保たれます。
政府。 国の税務当局が給付の査定をモダナイズします。適格性のルールは法律で定められ監査されるので、チームはルールを純粋な変換として形式仕様に書き、請求者が適格かつ不適格になることがない、すべてのケースが決定に至るといった主要な性質を検証し、監査人が結果を制定法までたどれるようにします。形式的な中核と並んで、チームは市民向けの受付フォームの使い捨てのプロトタイプを作り、本物のユーザーでテストします。複数ステップのウィザードがエラーを減らすことを学んだあと、プロトタイプを破棄し、受付を本番の水準で作り直します。アクティビティ図が、研修と監査のために、担当者の端から端までのプロセスを文書化します。結果の重いルールは形式的な厳密さを得て、不確実なユーザー体験は安いプロトタイピングを得て、どちらの手法も他方に属する場所には適用されません。
ビジネスケース: 動機、ROI、TCO
モデリングの見返りは、欠陥をより早く、修正がはるかに安いうちに見つけることから来ます。ホワイトボードで見つかった矛盾は数分のコストです。同じ矛盾が本番で見つかると、障害、手戻りのプログラム、規制された領域では法的責任のコストがかかりえます。モデルはまた、持続的なコミュニケーションとして働くことで、総所有コストを下げます。作者より長生きするシステム、企業や政府では普通のことですが、そのデータモデル、状態機械、主要なフローが正確に文書化されていれば、保守するコストははるかに安くなります。
コストは本物で、量らなければなりません。モデルは作るのに時間が、うまく作るのにスキルが、最新に保つのに継続的な労力がかかり、形式手法は専門的な労働を加えます。損益分岐点は、不確実性と結果によって決まります。両方が低い所では、重いモデリングは価値を破壊し、アジャイルのヒューリスティックが勝ちます。どちらかが高い所では、的を絞ったモデリング、そして重要な中核には形式検証が、高価な種類の失敗を防ぐことで何倍も元を取ります。リーダーシップに論拠を示すには、モデリングへの投資を、取り除かれた特定のリスクと、長寿命のシステムの保守性に結びつけてください。そして、モデルが実際に参照されているかを追跡してください。使われないモデルは純粋なコストだからです。
アンチパターンと落とし穴
- それ自体のためのモデリング: 決定に情報を与えるためではなく、プロセスが求めるから図を作ること。
- 真実として信頼される古いモデル: もうコードと一致しないのに、なお頼られている図。
- 大きな事前設計: コードの前に作られる網羅的なモデルで、最も少ない情報でなされた決定を固定すること。
- 図の乱立: あらゆるUMLの種類を一様に適用し、有用な少数の見方を雑音に溺れさせること。
- どこでも形式手法: 失敗の結果が正当化しないコードに、高価な検証を適用すること。
- 偶然のプロトタイプの昇格: 使い捨てのプロトタイプが、静かに製品として出荷されること。
- 実質より記法: モデルが問いに答えているかではなく、UMLの正しさについて議論すること。
成熟度モデル
- レベル1(開始): モデリングは場当たり的か存在せず、純粋に反応的です。手法は名指しされず、モデルは、描かれるとしても、一貫せず、分析されず、会議が終わるとすぐに放棄されます。
- レベル2(発展): 一部のチームは一般的な図を描き、名前のある手法に従いますが、実践は組織全体で不均一です。モデルは儀式的に作られることが多く、コードから乖離し、欠陥のために分析されることはまれです。
- レベル3(標準化): 共有の記法、文書化された手法の選択ガイド、一貫性のルールが定義され、組織全体で徹底されています。モデルは目的で選ばれ、システムと歩調を合わせて保たれ、欠陥のためにレビューされ、手法は各問題のリスクに合わせられます。
- レベル4(管理): モデリングはベースラインに対して測定され、制御されます。チームは、分析が実装前に捉える欠陥の数、モデルがコードからどれだけ乖離するか、各モデルが本物の決定のために実際に参照されたか、定義されたベースラインに対して節約された手戻りとサイクルタイムを追跡します。手法の選択は測定された不確実性と結果に合わせて調整され、重要な中核は合意されたカバレッジ目標に対して形式的に検証されます。
- レベル5(オーケストレーション): モデリングと手法の選択は継続的に改善され、組織全体でデリバリーとリスクの計画に統合されています。投資は不確実性と結果の変化に応じて適応し、モデルは証拠に基づいて日常的に最新に保たれ、退役させられ、深められ、形式的、ヒューリスティック、プロトタイピングの手法は、それぞれが見返りのある正確な場所に収まるよう組み合わされます。
議論のためのアイデア
- 直近のプロジェクトで、どのモデルが本物の決定に情報を与え、どれがプロセスが求めたから描かれただけでしたか。
- システムのどこで、形式仕様が元を取り、どこでは無駄になりますか。
- プロトタイプが使い捨てか進化的かをどう決め、その決定を徹底していますか。
- モデルがコードとずれていくのをどう防ぎますか。それとも、一部は代わりに削除すべきだと受け入れますか。
- あなたの文脈で、コードの前のモデリングの適切な量はどれくらいで、不確実性でどう変わりますか。
- 直近の本番インシデントを捉えたであろう振る舞いモデル(状態、シーケンス、アクティビティ)はどれでしたか。
要点
- モデルは目的のある抽象化です。それが情報を与える決定を名指しできないなら、描いてはいけません。
- 構造モデルと振る舞いモデルを具体的な問いに合わせ、一貫して最新に保ちます。
- モデルを分析します。確認されていないモデルは、テストされていない仮定です。
- ヒューリスティックでアジャイルな手法はほとんどのシステムに合います。形式手法は結果の重い中核のために取っておきます。
- プロトタイプで不確実性を取り除き、それが使い捨てか進化的かを前もって決めます。
- モデリングへの投資を、それが解決する不確実性と、決定を誤ったときのコストに比例させます。
参考文献とさらなる読み物
- IEEE Computer Society, SWEBOK Guide (Software Engineering Body of Knowledge), Version 4.0, Software Engineering Models and Methods knowledge area
- Martin Fowler, UML Distilled: A Brief Guide to the Standard Object Modelling Language
- Grady Booch, James Rumbaugh, Ivar Jacobson, The Unified Modelling Language User Guide
- Frederick P. Brooks, The Mythical Man-Month and No Silver Bullet: Essence and Accident in Software Engineering
- Daniel Jackson, Software Abstractions: Logic, Language, and Analysis (the Alloy modelling language)
- Leslie Lamport, Specifying Systems (TLA+)
- Simon Brown, Software Architecture for Developers (the C4 model)
- David Harel, Statecharts: A Visual Formalism for Complex Systems