📘

書評『入門 コンピュータ科学: ITを支える技術と理論の基礎知識』: 第7章 ソフトウェア工学

2023/09/11に公開

コンピュータ科学の基礎について改めて勉強し直してみようと思い、
『入門 コンピュータ科学: ITを支える技術と理論の基礎知識』を読んでいる。
本記事は「第7章 ソフトウェア工学」についての書評である。

この本について

『入門 コンピュータ科学: ITを支える技術と理論の基礎知識』はJ.Glenn Brookshear著
Computer Science: An Overview, 11th Edition の翻訳書である。
原著は1985年に初版が出版され、現在第13版まで出版されている。
アメリカでは多くの大学で初学年向けコンピュータ科学の教科書として使われている。

本書の構成は、「具体的なものから抽象的なものへ向かってのボトムアップのアプローチ」(p.6)をとっており、
章が進むごとに抽象度を増していく。
筆者はソフトウェアエンジニアリングの仕事に携わっており、
「第7章 ソフトウェア工学」は最も身近に感じられるトピックであると思われたので、
まずはこの章を読み、書評を書くに至った次第である。
各節ごとに内容のまとめと考察を記載するが、興味を持った度合いに応じて記述量が増減する。
特に言及することがなかった場合は考察を省略している。

本書の特徴として、各章末で社会問題の節を設けていることが挙げられる。
訳者いわく、「米国の大学では、日本のようにコンピュータリテラシの授業がないので、
社会的影響を考えることがコンピュータ科学入門の一環になっている」(p.11)とのことらしい。
この記事では扱わないが、本書の読者は一度目を通してみることをおすすめする。

第7章 ソフトウェア工学

ソフトウェア工学とは、大規模で複雑なソフトウェアシステムの開発を導く原理を探求する
コンピュータ科学の一部門である。
(p.302)

ソフトウェア工学の分野は日進月歩で研究が進んでいる。
本書が書かれたころと現在では状況が異なっていることもあるだろう。
しかしながら、本書が扱うのはソフトウェア工学の基礎的なトピックであるから、
ほとんどの部分について、そのエッセンスは現在においても有用であろうと思われる。
とはいえ取り扱われる内容が基礎的であるぶん、日常のソフトウェア開発活動に
そのまま応用できるものは少ないだろう。
というわけで本章を読む読者は、自らのソフトウェアエンジニアリングの経験と照らし合わせて
本書の内容をどのように適用できるかを考えながら読むと良いと思われる。

7.1 ソフトウェア工学という学問

ソフトウェアシステム開発にあたり検討が必要になる例として以下の例が挙げられている。

  • プロジェクトを完遂するのにどれくらいの時間や費用といった資源が必要になるか
  • どのように見積もればよいか
  • プロジェクトをどのように管理可能な部分に分割すればよいか
  • それぞれ制作された部分が正確に結合することをどのように確認すればよいか
  • それぞれの部分をどのように相互関連させればよいか
  • どのように進捗を計測すればよいか
  • どのように幅広い詳細に取り組めばよいか

工学の他の分野も同じようにこれらの問題を扱う。
しかしソフトウェア工学は他の工学と異なる性質があり、その相違点をを見過ごすと、
プロジェクトの失敗を招くという。
そこで著者は、「ソフトウェアと他の分野の製品との相違を特定することが
ソフトウェア工学という学問を前進させる第一歩となる」(p.302)と述べる。

ソフトウェア工学と他の工学の相違点について以下のようなものがあるという。

  • 伝統的な工学は、複雑な構造物を製作するとき、既成のコンポーネントを利用する。
    ソフトウェア工学でもその点は同じだが、課題がある(本章で述べられる)。
  • ソフトウェアの特性を計測するメトリクス(metrics)と呼ばれる定量的な技法の欠如
    • 品質の計測について、機械装置の場合は平均故障間隔で計測できるが、
      ソフトウェアは経年劣化しないので、この方法は適用できない。
    • ソフトウェアの特性を定量的に計測するのが困難なことは、ソフトウェア工学が
      機械工学や電気工学と異なり、基盤となる科学分野がないから。
      (機械工学や電気工学は物理学という強固な基盤がある)

ソフトウェア工学は基盤となる科学を探している段階であり、
実践家、理論家がそれぞれ異なるアプローチで探求している。

実践家と呼ばれる研究者は、当面応用できる技法の開発に携わる。
一方理論家と呼ばれる研究者は、将来の安定的な技法を構築するための基盤となる原理や理論を探求している。
(p.303)

コンピュータ工学のサブジャンル、コンピュータ支援ソフトウェア工学(CASE)により
CASEツールと呼ばれるさまざまなツールが開発されており、ソフトウェア開発においてさまざまな恩恵を享受できる。
「CASEツール」という呼称には馴染みがなかったが、以下のように開発を支援するツール全般を指すようである。

それら(筆者補足: CASEツール)には、(費用見積、プロジェクトスケジューリング、
そして人事管理を補助する)プロジェクト計画システム、
(開発プロジェクトの進捗管理を補助する)プロジェクト管理システム、
(各種仕様書の作成と構成を補助する)プログラミングシステムがある。
(p.303)

現代のソフトウェア開発者はこれらのツールを当然のように使うため恩恵をあまり意識することはないかもしれないが、
これらのツールなしで開発することを考えると、コンピュータ支援ソフトウェア工学に対する
感謝の念が湧いてくる(IDEやバージョン管理ソフトウェアがない時代のことを想像してみよ)。

7.2 ソフトウェアライフサイクル

7.2.1 サイクル全体

サイクル全体を以下のように表現していた。

開発
↓
使用(運用)
↓↑
保守

前節と同様、ソフトウェア工学と他の工学分野との相違点に著者は注目する。
「他の工業製品での保守段階は修理のプロセスであるのに対し、ソフトウェアの保守段階は、修正と更新が多い」(p.304)、
なぜなら一部の変更が他の変更を引き起こすからである。

ソフトウェアの開発段階で若干の労を厭わないことが、変更の段階で大きな助けになることが経験的にわかっている。
...
したがってソフトウェア工学研究の多くは、最小の努力で最大の成果が得られることを期待して、
ソフトウェアライフサイクルの開発段階に注がれている。
(p.305)

7.2.2 伝統的な開発フェーズ

伝統的なソフトウェア開発のライフサイクルの主なステップとして以下が記載されていた。

要求分析
↓
設計
↓
実装
↓
テスト

要求分析

著者は、要求分析の目標は「提案システムがどのようなサービスを提供するかを特定して、
そのサービスを提供するに際しての(時間制約やセキュリティといった)条件を識別して、
かつ外部世界がどのようにそのシステムと相互作用するかを定義すること」(p.305)であるという。
要求分析についての著者の見解については多くのエンジニアが共感するところであると思われるので、
少し長いが以下に引用する。

要求分析のプロセスは、ソフトウェアユーザの求めるものが何であるかを収集して分析するとともに、
プロジェクトの利害関係者間での要望、必要性、費用、実現可能性等のトレードオフについて交渉した上で、
完成したソフトウェアがもたなければならない機能とサービスを特定して、
最終的な要求をまとめる作業からなる。
これらの要求事項は、ソフトウェア要求仕様書と呼ばれる文書に記録される。
この文書は関係者全員の合意文書であり、ソフトウェア開発を導くとともに、
開発プロセスの中で議論が発生したときの解決の手段となるものである。
...
ソフトウェア開発者の視点から見れば、ソフトウェア要求仕様書は、
ソフトウェア開発を進める上での厳格な目標を定義するものである。
しかしながら要求仕様書は、この安定性を提供できないことがあまりにも多い。
ソフトウェア工学の研究者は、コミュニケーションの不足と要求仕様の頻繁な変更こそが、
ソフトウェア業界における制作費の超過と製品引き渡しの遅延の主たる要因であると主張する。
...
いずれにしてもソフトウェアのエンジニアは、プロジェクトの利害関係者との緊密で
率直なコミュニケーションが必須であると感じている。
(p.305-306)

設計

要求分析が提案されたソフトウェア製品の記述を提供するのに対し、
設計は、提案されたシステムの構築計画を作成することを含む。
ある意味要求分析は、解決すべき問題を特定することであり、
設計は、その問題の解法を構成することである。
(p.306)

よくいわれる分類「要求分析=システムが何をするか(what)、設計=システムがどのようにそれを達成するか(how)」
は誤りであると著者はいう。なぜなら要求分析でもhowについて考慮されるし、設計でもwhatについて考慮されるからだ。

また「確立された学問分野である建築学に比べると、ソフトウェア工学で実践される方法論は、
きわめて動的」(p.306)であるといい、具体的な設計手法はケースバイケースで選択されることを示唆している。

実装

実装には、実際のプログラミング、データファイルの生成、そしてデータベース開発といったものが含まれる。
(p.307)

テスト

ソフトウェア開発プロセスの中でプログラムだけがテストされるわけではない。
開発プロセス全体にわたって各中間ステップの成果物すべてが正確かどうか"テスト"されなければならない。
(p.307)

7.3 ソフトウェア工学の方法論

例:

  • ウォーターフォールモデル
  • インクリメンタルモデル、反復モデル
    • ラショナル統一プロセス(RUP)
    • プロトタイピング
    • アジャイルメソッド
      • エクストリームプログラミング(XP)

ウォーターフォールモデルとXPを比較することによって示される対照性は、
信頼性の高いソフトウェアを効率的に構成するすぐれた方法を追求しているソフトウェア開発プロセスに
幅広い方法論が適用されていることを表している。
(p.309)

7.4 モジュール性

7.2節で指摘した重要な点は、ソフトウェアを変更するためには最初にプログラムを理解しなければならない、
少なくともプログラムの関連する部分を理解しなければならないということであった。
そのような理解は、小規模なプログラムの場合でも困難な場合が多いだけではなく、
大規模なソフトウェアシステムではモジュール性(modularity)がなければほとんど不可能である。
つまりソフトウェアを、一般にモジュール(module)と呼ばれる、それぞれがソフトウェアの動作の一部を受けもつ
管理可能な単位に分割しなければならないということである。
(p.310)

7.4.1 モジュールによる実装

モジュールの分け方はさまざまである。
例えば命令型パラダイムとオブジェクト指向パラダイムでモジュールの構成要素が異なる。
「何がモジュールを構成するかが、最初のソフトウェア設計プロセスの目標を決定する」(p.310)ので、
この区別は重要である。

7.4.2 結合度

1つのモジュールの変更が、システムの他のモジュールにできるだけ影響しないようにする
=モジュール間の結合度を最小にすることが、モジュール化されたシステムを設計する際の目標となる。

ソフトウェアシステムの複雑さを計測する尺度の1つにモジュール間の結合度を計測するものがある。

モジュール間の結合度の形式:

  • 制御結合
    • 実行制御を1つのモジュールから他のモジュールへ渡すときに発生する
  • データ結合
    • モジュール間でのデータの共有度

7.4.3 凝集度

モジュール間の結合度を最小化するのと同様、モジュール内の結合度=凝集度を最大化するべきである。

  • 論理的凝集
    • 凝集度の弱い形式
    • 「そのモジュール内の構成要素が論理的に類似の動作を行うという理由で、同じモジュールに配置された場合」(p.314)
    • オブジェクト指向設計におけるオブジェクトは論理的凝集である
  • 機能的凝集
    • 凝集度の強い形式
    • 「そのモジュール内のすべての要素が、ある1つの動作を実行することでまとまっている場合」(p.314)
    • オブジェクト内の各メソッドは機能的凝集にするべき

7.4.4 情報隠蔽

情報隠蔽とは、情報をソフトウェアシステムの特定部分に制限することである。
ここでいう情報(information)とは、構造についてのすべての知識とプログラムユニットの内容を含む
広い意味で解釈される。すなわちデータ、使用されるデータ構造の型、符号化の体系、
モジュールの内部構造、手続きユニットの論理構造、そしてモジュールの内部的属性に関する
すべての要因が含まれる。
情報隠蔽の要点は、モジュールの動作が他のモジュールに不必要に依存したり、
不必要に影響を及ぼしたりしないようにするということである。
(p.314)

  • 情報隠蔽の設計目標
    • 「他のモジュールがその内部情報にアクセスしなくてもよいように設計しなければならない」(p.315)
      • 例: 凝集度の最大化、結合度の最小化
  • 情報隠蔽の実装目標
    • 「モジュールの協会が明確になるように実装しなければならない」(p.315)
      • 例: 局所変数の使用、カプセル化の適用、よく定義された制御機構

7.4.5 コンポーネント

「ソフトウェア工学における障害の1つに、大規模なソフトウェアシステムの構成に使用できる
既成の構築ブロックがないことを指摘した」(p.316)。
オブジェクトとクラスは潜在的にソフトウェア設計の既成の構築ブロックになり得る。
しかしそれらは構築ブロックとして小さすぎる。

つまりオブジェクトは、より一般的な概念であるコンポーネント(component)の特殊な場合なのである。
...
実際にはほとんどのコンポーネントは、オブジェクト指向パラダイムに基づいていて、
自己充足的なユニットとして機能する1つ以上のオブジェクトの集合である。
(p.316)

7.5 ツール

この節では、ソフトウェア開発の分析と設計段階を通して使用される
モデル化の技法と表記法の体系について学ぶことにする。
(p.317)

7.5.1 伝統的な技法

UML登場以前から存在するモデル図であり、現在も使用されているものとして以下が紹介されていた。

  • データフロー図
  • データディクショナリ

7.5.2 統一モデリング言語

代表的なUML図が紹介されている。

  • ユースケース図
  • クラス図
  • シーケンス図

また、UMLではないが、CRCカードが紹介されていた。
CRCカード…「オブジェクトの記述を書いておく索引カードのようなもの」(p.323)

7.5.3 デザインパターン

GoFのデザインパターンのうち以下が紹介されていた。

  • Adapterパターン
  • Decoratorパターン

7.6 品質保証

ソフトウェアの誤作動、予算超過、納期の遅れといったことがあまりに頻繁に生じるので、
ソフトウェアの品質管理方法を改善しなければならないことは明白である。
(p.324)

7.6.1 品質保証の範囲

品質に関するテーマ例:

  • 記録の保持
    • 開発プロセスの各ステップは、将来の参照のために文書化することがもっとも重要である。
      しかしこの目標は人間の性質と衝突する。つまり関連する文書を更新することなく決定を下したり
      決定を変更したりする誘惑に人間は抗しきれない。その結果不正確な記録が残り、
      将来その記録を使用するときに誤解が生じることになってしまう。
      (p.325)

    • CASEツールはドキュメンテーションを助けてくれる
  • レビュー

ドキュメンテーションの問題について重要なことを示唆している節である。
ドキュメントの作成・保守は人間の性質と衝突すると著者はいう。
ドキュメンテーションを楽にしてくれるものとしてCASEツールがあるが、これは根本的な解決にはならないだろう。
人はしばしば直感的に行動するが、直感は誤ることがある。
プロジェクトとしてやるべきことと人間の性質が衝突した場合、制度によって解決する必要がある。
この点については行動経済学の研究成果が役立つであろう。例えばナッジという概念があり、
集団にとって良いと思われる行動を人々が選択しやすいようにインセンティブを与えておくことである。
このことは7.8節「ヒューマンマシンインターフェース」にも関連がある。

7.6.2 ソフトウェアテスト

複雑なプログラムのすべてのあり得る経路をテストすることは不可能なので、
限られた回数のテストによって効率的にエラーを発見する必要がある。
ソフトウェア工学はこれまでの経験から、ソフトウェア中のエラーは、システム中でも
少数のモジュールに中秋的に現れる傾向があることがわかっている。

  • 基礎パステスト
  • グラスボックステスト
  • ブラックボックステスト
    • 境界値分析法
    • ベータテスト
    • アルファテスト

7.7 ドキュメンテーション

ソフトウェアシステムは、人々がその使用法を習い保守できなければ使い物にならない。
つまりドキュメンテーションは、最終ソフトウェアパッケージの重要な部分であり、
したがってその開発はソフトウェア工学の重要なトピックである。
(p.327)

  • ユーザドキュメンテーション
    • 目的:
      • 「ソフトウェアの機能を説明してどのように使用するかを記述すること」(p.327)
    • 「ユーザが読むことを期待して、アプリケーションの用語を使って記述されている」(p.327)
    • 優れたユーザドキュメンテーションは販売に寄与する
  • システムドキュメンテーション
    • 目的:
      • 「ソフトウェアの内部構造を記述することであり、ソフトウェアライフサイクルの
        後半での保守作業に資するためのものである」(p.328)
    • 構成要素:
      • 「すべてのプログラムのソースコード」(p.328)
        • 「それらのプログラムが人間に読める形式で表現されていることが重要」(p.328)
      • 「ソフトウェア要求仕様を含む設計文書の記録と、
        設計を通してこれらの仕様がどのように獲得されたかを示す記録」(p.328)
  • 技術文書
    • 目的:
      • 「(パラメータの調整、更新のインストール、そしてソフトウェア開発者に問題を報告するといった)
        ソフトウェアをどのようにインストールしてサービスするかを記述するもの」(p.328)

PCの世界では、技術文書とユーザドキュメンテーションの境界は曖昧である。
なぜならユーザがソフトウェアをインストールして各種サービスを行うことが多いからである。
(p.328)

プログラムのソースコード自体をドキュメントとして捉えているのが面白い。
プログラマはメンテナンス性の高いソースコードを書くことに注力するが、
一方でその他のドキュメントの品質については、その重要性を理解しつつも、
コーディングほど熱意をもって取り組むことは少ないのではないかと思われる。
7.6.1節でも述べたが、ドキュメンテーションに関する何らかのインセンティブ設計が必要である。

7.8 ヒューマンマシンインターフェース

人間がソフトウェアシステムを抽象化ツールとして使用できなければならないので、
「使いやすくかつシステムと人間のユーザとの間のコミュニケーションエラーを最小化(理想的には削除)
するよう設計されなければならない」。(p.329)

結局のところ、人間は、内部的動作がいかに巧みに実行されているかではなく、
システムの使い勝手のよさによってシステムそのものを判断する。
...
したがってシステムのインターフェースの設計は、ソフトウェア工学プロジェクトの
成否の鍵を握る決定的要因なのだ。
(p.329)

ヒューマンマシンインターフェース設計の研究の源泉:

  • エルゴノミクス
    • 「人間の生理的機能と調和するシステムの設計を扱う」(p.329)
    • コグネティクスに比べ過去の研究の蓄積があり、よりよく理解されている
  • コグネティクス(cognetics)
    • 「人間の精神的機能と調和するシステムの設計を扱う」(p.329)
    • エルゴノミクスに比べ発展途上
      • 扱われる問題の例:
        • 習慣化により人間の注意力が下がる現象
        • 人間の注意力の狭小さ(集中していると周りが見えなくなる現象)
        • 心が同時に扱うことのできる事柄の限界
          • cf. Psychological Review中のジョージ・ミラーの論文(1958年)
            • 人間の精神が、同時に約7つの事柄しか扱うことができない

ヒューマンマシンインターフェース設計の分野での計測尺度研究の代表例として、GOMSモデルがある。

  • GOMSモデルの基礎となる方法論:
    • Goal
      • ユーザの目標
      • 例: テキストから単語を削除する
    • Operator
      • 操作
      • 例: マウスボタンをクリックする
    • Method
      • 方法
      • 例: マウスボタンをダブルクリックしてから削除キーを押す
    • Selection rule
      • 選択規則
      • 例: 同一の目標を達成するのに2つの方法のうちどちらを選ぶか

コグネティクス(cognetics)という概念は日本においてはあまり一般的ではないのではないだろうか。
行動経済学や神経経済学などとも親和性のある概念かと思われる。

7.9 ソフトウェアの所有権と責任

  • 知的財産法
    • 著作権法
    • 特許法

ソフトウェアライセンス

著作権とソフトウェアライセンス合意文書は、ソフトウェアの不正なコピーや承認されない使用を
禁止する法的効力をもつが、第三者がほとんど同じ機能をもつ製品を独立に開発することを防止するには不十分である。
真に革命的なソフトウェア製品の開発者が、その発明から十分な利益を得ることができない事由が
何年にもわたって続いている(2つの顕著な例は表計算ソフトとウェブブラウザである)のは、
悲しむべきことである。
(p.332)

製造物責任

製造物責任を問われないようにするためにソフトウェア開発者は、製品についての責任を限定する
免責条項をソフトウェアライセンス中に含めることが多い。
...
しかしながら裁判所は、原告が被告の過失を示すことができたときには免責条項を認めることは
ほとんどない。
...
つまりソフトウェアの製造物責任訴訟を回避する最良の方法は、ソフトウェア開発を通じて
健全なソフトウェア工学の原則を適用し、ソフトウェアアプリケーションに応じた注意を払い、
それらの努力を証明する記録を作成して保存しておくことなのだ。
(p.333)

まとめ

本書は入門書であるため全体を通して多くのエンジニアにとって既知の内容が書かれており、真新しさはない。
しかし、普段業務において無意識的に行っていることが言語化されており、
またその内容も基礎的であるため、本書の内容と普段の業務内容を相対化させることで、
該当業務の標準からの逸脱度合いをある程度把握することができる点は有用である。

7.1節で触れられた「ソフトウェアの特性を計測する定量的な技法の欠如」は本章全体を通して
1つのテーマのように扱われていると感じた。
ソフトウェアの特性を計測する定量的な技法の欠如の弊害として、
「本来こうあるべきだが往々にしてそうはならない」事例が各節で述べられており、
職業エンジニアの読者は思い当たることも多いのではないかと思う。
筆者においては、これらの問題について認知はしつつも、しかし決定的な有効打がなく、
またその問題に向き合うための時間が取れないというのが現状である。
この問題の対処法の1つは、問題から目を背けることだ。
エンジニアとしての責務を果たすべきだと誹りを受けるだろうが、
その問題に向き合うことが構造上困難である現実は、
いち会社員エンジニアにとっては如何ともし難い、というのが正直な感想である。

参考文献

サポートのお願い

読んでいただきありがとうございます。バッジを贈って応援いただけると今後の励みになります。サポートお待ちしております。

Discussion