Comments
Description
Transcript
資料4(ソフトウェア保守/再利用)
ソフトウェア⼯学 (part 4) 情報メディアシステム分野 手塚太郎 ソフトウェア保守 ソフトウェア保守とは z 計算機にインストールされたソフトウェアを維持・管理する作業 ソフトウェアをつねに正しく稼働させることが⽬的 z 開発の繰り返しを促進する作業 ソフトウェア進化(software evolution) – ソフトウェアを永続的に発展 – 機能拡張,機能変更,性能改善,環境への適合 機能拡張 機能変更 性能改善 環境への適合 ソフトウェア変更の積極的な取り込み – ソフトウェアは本質的に変化(修正,変更)し続ける ソフトウェアは本質的に変化(修正 変更)し続ける – はじめから完全なソフトウェアを構築するのは困難 z 保守における戦略 保守して利⽤し続けるか vs. 破棄して作り直すか – ソフトウェア変更と新規開発のコストの⽐較 ソフトウ ア変更と新規開発の ストの⽐較 – 特に,レガシーソフトウェア(legacy software)の場合 プログラム進化の法則(Lehman)を考慮 プ グ – 継続的な変更が必須,変更による複雑度の増⼤など 2 ソフトウェア保守作業 z 保守対象 ソ ソースコードの変更だけではない スコ ドの変更だけではない ソフトウェア開発⼯程で作成されたすべての成果物 要求仕様書,設計仕様書,ソースコード,テスト 要求仕様書 設計仕様書 ソ スコ ド テスト ケース,マニュアルなど z 保守者(CE: 保守者 customer engineer)が実施 が実施 ソフトウェア開発のすべての⼯程に関する知識が必要 – 顧客 ソフトウェア 要求分析 要求 変更 保守者 設計 設計 改善 保守 実装 誤り 修正 テスト インストール 計算機 3 ソフトウェア保守の分類 z 修正保守(corrective maintenance) 運⽤段階で検出された残存エラ 運⽤段階で検出された残存エラー(誤り)の修正 (誤り)の修正 故障に対するソフトウェアの修正 z 適応保守(adaptive maintenance) 動作環境や利⽤環境の変化に追従するための変更 業務の拡⼤,ハードウェアの進歩,OSの更新など 業務の拡⼤ ハ ドウェアの進歩 OSの更新など z 改善保守/完全化保守(perfective maintenance) 機能拡張(変更)や性能向上のための変更 – 暗号化の導⼊,検索速度の向上,メニューの改変など 管理のしやすさを向上させるための変更 管理 やすさを向上さ ため 変更 – 設計の改善,ソースコードの書き換え,オブジェクト 指向 の切り替え コンポ ネント化など 指向への切り替え,コンポーネント化など z 予防保守(preventive maintenance) 故障を未然に防ぐための修正 修 潜在的な誤りの除去 – 4 ソフトウェア理解 z 保守では,現在稼働中のソフトウェアを理解するこ とが重要 どのような要求に対して開発されたのか どのような設計指針のもとで開発されたのか どのようなアーキテクチャが採⽤されているのか ど よ な キ クチ が採⽤され か モジュ モジュール構成はどのようになっているのか ル構成はどのようになっているのか どのようにプログラムで実現されているのか どのようなテストが⾏われてきたのか ど が⾏ …… z ソフトウェア理解を⽀援する様々な保守技法が提案 されている。 5 保守技法 z 構成管理(configuration management) z 影響分析(impact analysis) z 回帰テスト(regression testing) z ソフトウェア視覚化(software visualization) z ソフトウェアリエンジニアリング(re-engineering) z プログラム理解(program understanding) 6 構成管理 z ソフトウェア開発に含まれる構成要素やプロセスを⼀貫して管 理する作業 成果物に対する付加情報(メタデータ: meta data)を管理 – ある成果物はどのプロジェクトにおいて作成されたのか ある成果物はどのプロジ クトにおいて作成されたのか – 開発のどの段階で作成されたのか(要求? 仕様? 設計?) – 誰がいつ作成したのか – 誰がいつどのようなテストを⾏ったか 成果物間の対応関係を管理 – 仕様書の記述とそれを実現するモジュ 仕様書の記述とそれを実現するモジュールとの関係など ルとの関係など z 過去に適⽤された変更を管理する作業(版管理) バージョン(版: バ ジ ン(版 version)とリリース(release)を管理 i )とリリ ス( l )を管理 – バージョン: 利⽤者の要求を満たす特定の構成(スナップ ショット: snapshot) 7 リリース: 以前のソフトウェアを修正あるいは改善したもの 構成管理システム 関係を 把握 仕様書 変更を 把握 設計図 マニュアル テストケース 第1.2版 第1.3版 ソ ス ソースコード ド 第1.1版 版を把握 開発者/保守者 構成管理 システム 第2.1版 第 版 8 影響分析 z 保守における変更による影響が及ぶ範囲(影響を受けるモジュー ル)を把握する作業 保守による変更は直接変更を適⽤した部分だけにとどまらず, 他の多くの部分に影響を及ぼす z 影響範囲を変更前に解析し,必要な資源や⼯数を⾒積もる作業 z 実際に変更を⾏った後に,ソフトウェアの⼀貫性が維持されてい るかどうかを検査する際にも適⽤ 波及効果解析(ripple effect analysis) z 保守において新たな誤りを混⼊させる危険性や内部に発⽣した⽭ 盾によりソフトウェアが動作しなくなる可能性を減少 z 多くの影響分析⼿法はプログラムコード(ソースコード)を対象 クロスリファレンス情報に基づき影響範囲を特定 – 変数の宣⾔と利⽤,関数の呼び出し元と呼び出し先などの 関係 ワークプロダクト(成果物)間の依存関係に基づき影響範囲を 9 特定 要求R1 モジュールM1 R2 設計D1 R3 D2 D3 M3 D4 D6 D5 D7 M4 M5 … ワーク プロダクト M2 ソースコードS1 テストケースT1 S2 T2 S3 T3 S4 T4 S5 T5 … モジュール構成図 … 要求仕様書 … ワークプロダクト間の依存関係 垂直追跡可能性 (vertical traceability): 各⼯程内部における依存関係 ⽔平追跡可能性 ((horizontal traceability): y) ⼯程を横切って派⽣する依存関係 10 回帰テスト z 以前のソフトウェアで動作していた機能が,新規あるいは修正 後のソフトウェアで正常に動作するかどうかを検査する作業 z 未変更部分がもとの通り正常に動作するかどうかを確認する作 業 変更前に適⽤されたテストケースをそのまま利⽤ 既存のソフトウェアをテスト対象ソフトウェアに置き換え る場合や稼働中のソフトウェアに修正を⾏った場合に実⾏ z 保守における新たな誤りの混⼊を防⽌ ソフトウェアを少しずつ変更するたびに実施 テストの⾃動化が重要 – 同じテストの繰り返しを回避 11 ソフトウェア視覚化 z ソフトウェアに関わるさまざまな情報を⼈間が理解しやすい形式で 表現すること z 視覚化の観点 構造: プログラムを実⾏せずに抽出可能なソフトウェアの静的 な要素やそれらの関係を可視化 – ソースコードの⾊づけ ソ スコ ドの⾊づけ – ソフトウェアの構成要素間の関係の図⽰ – 各種ドキュメントの特性(規模や複雑度など)を図⽰ 振る舞い: 実際あるいは抽象的にプログラムを実⾏させること で取得したデ タを可視化 で取得したデータを可視化 – 実⾏の経路やアルゴリズムのアニメーション化 – 実⾏時の関数呼び出しやメッセージのやり取りを図⽰ – テスト結果を図⽰ 進化: ソフトウェアの開発プロセスを可視化 12 – 過去の変更箇所を⾊分けして表⽰ ソフトウェア視覚化の例 CodeCity b U by Univ. i Lugano L SeeSoft by AT&T by FSE at Ritsumeikan Univ. 13 ソフトウェアリエンジニアリング z 既存のソフトウェアを新たに構成し直すことで,若返らせる作業 リバースエンジニアリング リバ スエンジニアリング + フォーワードエンジニアリング フォ ワ ドエンジニアリング リバースエンジニアリング(reverse engineering) – ソースコードから設計図や要求仕様を回復 ソ スコ ドから設計図や要求仕様を回復 フォーワードエンジニアリング(forward engineering) – 通常の開発 通常 開発 要求 フォーワード エンジニアリング 設計 リバース エンジニアリング 実装 リエンジニアリング リストラクチャリング 14 ソフトウェアリストラクチャリング z リストラクチャリング(再構成: restructuring) 外部から⾒ 外部から⾒た振る舞いを変えずに,同じ抽象レベルの別の表 振る舞 を変えず ,同 抽象 別 表 現に変換する作業 – 複雑な処理を単純な処理に分割して記述,実⾏されない命 , 令を取り除く,内部アルゴリズムを取り替えるなど リファクタリング(refactoring) g – ⼤きな設計変更を⼩さな変換の繰り返しで実現することで, 外部的挙動を保存したままで内部構造を改善 z リドキュメンテーション(再⽂書化: redocumentation) プログラムコード(多くの場合,ソースコード)を解析するこ ( , ) とで,それに明⽰的に記述されていない情報を抽出し,⼈間 が理解しやすい⽂書を作り出す作業 z デザインリカバリ(design recovery) プログラムコードや設計情報からより抽象レベルの⾼い設計 情報を回復 15 領域(ドメイン)知識や外部知識,推論を利⽤ ソフトウェアリファクタリング 環境の変化 外部的挙動を保存した コード変換 変換 機能改変 開発直後の ソースコー ド 設計や実装の 設 実装 劣化 劣化した 改善後の ソースコー リファクタリング ソースコード ド 機能拡張 不吉な匂い(bad 不吉な匂い(b d smell): ll) 潜在的な問題や ⽋陥に関する兆候 B A D Aʼ Bʼ C 理解しにくい 変更しにく 変更しにくい Dʼ D Cʼ C 理解しやすい 変更しやすい 16 プログラム理解 z 実際に稼動している実体はプログラム プログラムが保守にとって唯⼀信⽤できる成果物 プ グ ムが保守にと 唯 信⽤ き 成果物 実際の現場では,過去に改善された内容が,要求仕様 書や設計仕様書に反映されていないという状況は頻繁 に発⽣ z 保守作業ではプログラム理解は不可⽋ プ プログラム理解が必須であることが保守作業を難しく グラム理解が必須である とが保守作業を難しく している最⼤の原因 z プログラム理解を⽀援する技法 制御フロー解析(control flow analysis) データフロー解析(data デ タフロ 解析(data flow analysis) 依存関係解析(dependency analysis) プログラムスライシング(program slicing) 17 制御フロー解析 z プログラムの制御の流れ(制御フロー)を解析 z プログラムに現れる分岐や繰り返しを明確化 プログラムを直接読むよりも実⾏イメージが把握しやすい 制御フローグラフ ((CFG: control flow g graph) p ) 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: int func(int data[], int n) { int sum = 0; int prod = 1; int i = 0; while (i < n) { sum = sum + data[i]; prod = prod * data[i]; i = i + 1; } print(sum); プログラムの print(prod); p (p ) ソースコード 1 2 3 4 5 6 10 11 7 8 18 データフロー解析 z プログラム中のデータの定義と参照の関係を解析 z あるデータがプログラムのどの部分に関与するのかを明確化 計算過程が追いやすくなるため,プログラムが何を計算して いるかが把握しやすい 1 Def = { data[], n), Use = { } 2 Def = { sum ), Use = { } 3 Def = { prod )), Use = { } 4 Def = { i ), Use = { } 5 Def = { ), Use = { i, n } 6 Def = { sum )), Use = { sum sum, data data, i } 7 Def = { prod ), Use = { prod, data, i } 8 Def = { i ), Use = { i } データフロー(data flow) 10 Def = { ), Use = { sum } 11 Def = { ), Use = { prod } 19 依存関係解析 z 制御フロー解析とデータフロー解析の結果を⽤いることで, プログラム内部に潜在する依存関係を抽出 制御依存関係(control dependence) – 6⾏⽬の⽂が実⾏されるかどうかは,5⾏⽬のwhile⽂ の条件判定の結果で決まる デ データ依存関係(data タ 係( dependence) p ) – 2⾏⽬で定義されたsumの値が6⾏⽬で参照される sumの値に到達 z ソースコードの影響分析に利⽤ 1 2 sum 10 sum 8 i n data sum 4 i i 6 sum i i data 5 prod prod 3 prod 7 prod 11 プログラム依存グラフ グラ 依存グラ (PDG: program dependence graph) 制御依存関係 デ タ依存関係 データ依存関係 20 プログラムスライシング z ある変数の値に関係する命令だけを,もとのプログラムか ら抽出 変数の値はプログラム全体に影響を受けるのではなく, 限定された命令によってのみ影響を受ける z プログラムスライス(program slice) 抽出した命令の集まり(コ 抽出した命令の集まり(コード) ド) プログラム依存グラフにおいて着⽬する命令から制御 依存関係⽮印とデータ依存関係⽮印をたどることによ 依存関係⽮印とデ タ依存関係⽮印をたどることによ り計算 21 プログラムスライスの例 z 静的スライス(static slice) すべての⼊⼒データ(変数が取りうる値)に対して解 析 z 動的スライス(dy 動的スライス(dynamic a c slice) s ce) 特定の⼊⼒データ(実⾏系列)に対して解析 z 逆⽅向スライス(backward slice) 変数の値に影響を与える可能性のある命令の集まり 変数 値に影響を与え 可能性 あ 命令 集まり z 順⽅向スライス(forward slice) 変数の値が影響を与える可能性のある命令の集まり 22 プログラムスライスの例 1 2 4 8 10 スライス基準 6 3 5 7 11 もとのプログラム 1: 2: 3: 4: 5: 6: 7: 8 8: 9: 10: 11 11: int func(int data[], int n) { int sum = 0; int prod = 1; int i = 0; while (i < n) { sum = sum + data[i]; prod = prod * data[i]; i = i + 1; 1 } print(sum); print(prod); p int(p od) 1: 2: 3: 4: 5: 6: 7: 8 8: 9: 10: 11 11: 10⾏⽬の変数sumに関する ⾏⽬ 変数 関 静的逆⽅向スライス int func(int data[], int n) { int sum = 0; int i = 0; while (i < n) { sum = sum + data[i]; i = i + 1; 1 } print(sum); 23 ソフトウェアの再利⽤ ソフトウェア再利⽤とは z 開発されたソフトウェア(成果物)の⼀部や開発によって得ら , れた知⾒を,次の開発で活⽤すること 再利⽤資産(reusable asset) – ソ ソースコード スコ ド – 要求,仕様,設計図,テストケース,マニュアル – ツール,開発プロセス,開発経験や知⾒ ツ ル 開発プロセス 開発経験や知⾒ 再利⽤部品/コンポーネント(reusable component) – 再利⽤資産を再利⽤に適した形で汎⽤化したもの 部品作成 部品の選択,カスタマイズ, 部品の選択 カスタマイズ 組み⽴て 再利⽤部品 既存のソフトウェア 要求分析 新しいソフトウェア 設計 実装 テスト 25 再利⽤は計画的に z 開発の段階で成果物が再利⽤されることを明確に意識するこ とが重要 場当たり的に⾏う個⼈活動ではない z 再利⽤されやすいようにソフトウェアの実装を進めていく。 26 ソフトウェア再利⽤の意義 z 過去の資産を有効に活⽤することが開発を成功させる鍵 ソフトウェアをゼロから開発することは⾮効率 ソフトウ アをゼロから開発することは⾮効率 – – 適切な再利⽤部品を容易に検索し,簡単に組み合わせる ことで⽣産性を向上 と ⽣産性を向上 ⼗分な信頼性を持つ再利⽤部品を組み合わせることで信 頼性の⾼いソフトウェアを構築可能 開発の総コスト 再利⽤を意識しない開発 再利⽤を意識した開発 再利⽤資産の 開発コスト 開発数 27 ソフトウェア再利⽤の分類 z ⽣産者側での再利⽤(producer reuse) 再利⽤資産を提供 – アプリケーション領域の分析と再利⽤部品の作成 vs. vs z 消費者側での再利⽤(consumer 消費者側での再利⽤( reuse)) 再利⽤資産を使⽤(検索,カスタマイズ,組み⽴て) 28 ソフトウェア再利⽤の分類 z ブラックボックス再利⽤(black-box reuse) 再利⽤資産を変更無しで,そのまま使⽤ – 再利⽤の効果は⼤,再利⽤の機会は少ない vs. vs z ホワイトボックス再利⽤(white-box イ ボ ク reuse) 再利⽤資産を要求に合わせて部分的に変更して使 ⽤ – 再利⽤の機会は多,再利⽤資産を理解する労⼒ , が必要 29 ソフトウェア再利⽤の分類3 z 垂直的再利⽤(vertical reuse) 同⼀プロジェクトや同⼀アプリケーション領域で 同⼀プロジェクトや同⼀アプリケ ション領域で の再利⽤ vs. z ⽔平的再利⽤(horizontal 平 再 ⽤( reuse)) プロジェクトやアプリケーション領域を横切る再 利⽤ 30 ソフトウェア再利⽤技法 z オブジェクト指向におけるクラス 独⽴性の⾼いモジュ 独⽴性の⾼いモジュール ル 実装の隠蔽(カプセル化)による置換が容易 – 継承により既存クラスの 継承により既存クラスの⼀部を再利⽤ 部を再利⽤ 粒度が⼩さく,再利⽤の効果が限定的 z オブジェクト指向フレームワーク(object-oriented framework) クラスとそのインスタンス間の相互作⽤を内包 – クラスだけでなく,クラスの利⽤⽅法も再利⽤ クラスだけでなく クラスの利⽤⽅法も再利⽤ 開発者がカスタマイズ(拡張および変更)可能な半完成アプリ ケ ション ケーション – アプリケーションの⼀部をフレームワークにはめ込み z コンポ コンポーネント指向開発(component-based ネント指向開発(component based development) コンポーネントを組み合わせることでソフトウェアを構築 z ソフトウェアパタ ソフトウェアパターン(software ン(software pattern) ソフトウェア開発において蓄積された経験や知⾒の再利⽤ 31 – オブジェクト指向とコンポーネント指向 z オブジェクト指向 データのカプセル化 デ タのカプセル化 各クラスの操作は直接アクセス可能 z コンポーネント指向 コンポ ネント指向 クラス(インスタンス)のカプセル化 インタフェースを介してのみアクセス可能 インタフ スを介してのみアクセス可能 – – クラス クライアント クラス 提供インタフェース(provided interface) 要求インタフ 要求インタフェース(required ス( i d iinterface) t f ) クラス クラス クラス オブジェクト指向 提供インタフェース クラス クラス クライアント クライアント クラス コンポーネント コンポ ネント 要求インタフェース コンポーネント指向 32 ソフトウェアコンポーネント z インタフェースにより明確に定義されたサービスを提供あるいは 要求し,実装の詳細が隠蔽 要求 ,実装 詳細 隠蔽 振る舞いとその実装が分離 z 標準化された特定のコンポ 標準化された特定のコンポーネントアーキテクチャ上で動作 ネントア キテクチャ上で動作 コンポーネントアーキテクチャ – コンポ コンポーネントの配置やコンポーネント間の通信を提供 ネントの配置やコンポ ネント間の通信を提供 グルーコード – コンポーネントどうしを接続する糊付けコード コンポ ネントどうしを接続する糊付けコ ド コンポーネント コンポ ネント グルーコード コンポーネント インタフェース コンポーネントアーキテクチャ 33 プロダクトライン開発 z 再利⽤技術に基づく類似プロダクトの開発 共通の管理された特徴を持つ 管 共通性(commonality)と可変性(variability)の認識 各プロダクトの個別最適ではなく,プロダクト群の全体最 適を⽬標とする – プロダクトライン に関する 要求や制約など プロダクトライン への要求の定義 コア資産 (再利⽤資産) 再利⽤可能な 要求 プロダクトに関する 要求や制約など プロダクトへの 要求の定義 要求 定義 プロダクトライン アーキテクチャ の設計 再利⽤可能な コンポーネント の実装 プロダクトライン アーキテクチャ 再利⽤可能な コンポーネン ト プロダクトの 設計 プロダクトの 実装 最終プロダクト 34 ソフトウェアパターン z 開発者の経験や知⾒を再利⽤できるように体系化したもの z ソフトウェア開発において繰り返し現れる問題に対する解法,指 ソフトウェア開発において繰り返し現れる問題に対する解法 指 針,知⾒に名前を付与してテンプレート化したもの パターンはそのまま組み込む再利⽤部品ではない – もしろソフトウェアの⼀部をパターンとして抽出 z ソフトウェア開発の各局⾯で頻繁に現れる構造や原則 z 熟練開発者たちの過去の成功例 z コミュニケーションを効率的に⾏うための標準的な語彙 コミ ケ シ ンを効率的に⾏うための標準的な語彙 パターンは名前をもつ z パターン記述 パ どのような状況(context)で利⽤する どのような問題(problem)に適⽤できる どのように問題を解決(solution)する どのような結果(consequence)や効果(利点や⽋点)を与える 35 ソフトウェアパターンの概念 z 状況の共通性に基づき抽象化した問題とその解法および結果の組 状況 パターン 問題 抽象化 問題1 解法 問題3 繰り返し発⽣ する問題 問題2 状況 結果 具体化 解法 解法3 解法1 繰り返し適⽤ される解法 解法2 結果 36 パターン指向ソフトウェア開発 問題領域 概念モデル プロダクト パターン ビジネスパターン アナリシスパターン アナリシスパタ ン 解決領域 分析モデル デ 設計モデル 計 デ 実装 デル 実装モデル アーキテクチャパターン デザインパターン コーディングパターン テストパターン 開発プロセス 保守パタ ン 保守パターン 開発組織 プロセスパターン マネジメント ネジメ ト パターン 37 ソフトウェアパターンの種類 z ビジネスパターン(business pattern) ビジネス領域で必要となる典型的なデータや概念,ビジネス ビジネス領域で必要となる典型的なデ タや概念 ビジネス z z z z に登場する典型的な⼈物・もの・活動,ビジネスプロセス アナリシスパターン(analysis アナリシスパタ ン(analysis pattern) 典型的な分析モデルの集まり アーキテクチャパターン(architectural ア キテクチャパタ ン(architectural pattern) システム全体の構造や振る舞いに関する良い設計 ソフトウェアシステムの基礎的かつ典型的な構造 デザインパターン(design pattern) システムの構成要素の構造や振る舞いに関する良い設計 – 設計の意図や設計プロセスを明確化 特定のプログラミング⾔語に⾮依存 コーディングパターン(coding patterns) イディオム,良く知られたアルゴリズム,コーディング規約, イディオム 良く知られたアルゴリズム コーディング規約 命名規則など 38 ソフトウェアパターンの種類 (contʼd) z テストパターン(testing pattern) テスト⽅法やテスト計画の優れた指針 z 保守パターン ソフトウェアプロダクトの改訂や改善に関する優れた指針 ソフトウ アプロダクトの改訂や改善に関する優れた指針 や変更⽅法 z プロセスパターン(process pattern) ソフトウェア開発における⼈員,プロジェクト,プロダク トを管理する優れた指針 – 組織構造を最適化する指針 – ⽣産性の⾼い開発プロセスに共通する指針 z アンチパターン(anti pattern) 過去の失敗から学んだ教訓 解決の悪い⾒本 「すべきでないこと」の集まり 39