【備忘録】ソフトウェア開発

#要求分析

## 要求モデル

システム構成や機能的要求等が要求仕様書に含まれるが、
このうち「機能的要求」は形式的な要求モデルを用いて記述されることが多い。
(機能階層モデル、データフローモデル、ERモデル、有限状態機械モデルなど)

- (要求モデル1)機能階層モデル
    - 機能全体を体系的/組織的に表現するのに適している

<img width="592" alt="機能的要求.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/271543/5f30ef45-015a-2488-7bd1-89cd561ac7b6.png">

- (要求モデル2)データフローダイアグラムモデル
    - 業務処理におけるデータの流れを表す
    - 【メリット】DFDの技法は、構造化分析で使われるもので、データの明確な流れを知ることで、無駄を見つけ、合理化・効率化できる箇所の発見に役立つ。
    - まず大まかな記述(レベル0)から詳細な記述(レベルX)へと落とし込んでいく
   

<img width="600" alt="dfd.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/271543/985aac1d-fe58-a118-a46f-98e058c7c314.png">


- (要求モデル3)有限状態機械モデル
    - 状態遷移図(表)で表現
    - 【メリット】制御の前提条件、異常ケースを含めて、状態を全てを網羅的に表現できる

 <img width="602" alt="状態遷移図.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/271543/164ab4f0-5170-89cf-d32f-f3d863ce7adf.png">

## 要求モデルの検証

- 検証観点
    - 性能 <font color="Red">×</font>
    - 機能 <font color="Red">×</font>
    - 可用性 <font color="Red">×</font>
    - 保守性 <font color="Red">×</font>
    - 金額 <font color="Red">×</font>
    - <font color="Red">検証可能性</font>
    - <font color="Red">実現可能性</font>
    - <font color="Red">正常性(ユーザーが望んでいること)</font>
    - <font color="Red">完全性(重要な情報が欠落していないこと)</font>


- 検証方法
    - 要求仕様書のレビュー
    - プロトタイプの提出

# ソフトウェア設計
- 要求仕様からプログラム仕様をアウトプットする変換工程が設計
- ソフトウェア設計は外部設計と内部設計の2つに分かれる

##　外部設計

- 外部インターフェースの再定義
- システムをサブシステムごとに分解
- サブシステム間の<font color="Red">データと制御の流れ</font>を決定

##　内部設計
(各サブシステムごとに...)

- 物理的なプログラムの配置
- ~~各モジュール~~ <font color="Red">各モジュール仕様の決定</font>
- アルゴリズムとデータ構造

## 良い設計
- 要求品質を満たしたソフトウェアのこと
- 品質とは...
    - 機能
    - 性能
    - 保守性
    - 可用性
    - <font color="Red">セキュリティ</font>
    - <font color="Red">安全性</font>
   

### 良い設計のための2つの戦略
まず問題として挙げられるのは、<font color="Red">「複雑ゆえにのちに手戻りが発生すること」</font>

- 対策①：抽象化(余計な情報をそぎ落し、本質のみをとらえる)
- 対策②：分割と階層化(問題の範囲を狭める)
    - システムを複数の独立部分に分け、それぞれに設計する
    - <font color="Red">(ポイント)要素間の独立性</font>を高めることで、設計変更時の影響が少なくて済む


<img width="563" alt="分割階層化.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/271543/02590eaf-27bb-5e31-3f0d-58dba29f8f24.png">

## モジュール分割

大きく分けて、「データの流れに注目して分割」、「データの構造に注目して分割」「共通の機能を抜き出す分割」の3つの技法がある


### 複合設計法(データの流れに注目して分割)

- sts分割とtr分割がある

#### sts分割

機能をデータの変換過程と捉え、1つの機能を入力・処理・出力の3つの機能に分割する手法

<img width="581" alt="sts分割.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/271543/f7135eb7-b528-8437-fddc-9fff52f2695a.png">

#### tr分割

<font color="Red">入力データに応じて処理が変わる場合に用いる手法。</font>

主にsts分割を行い、sts分割でうまく行かない場合にtr分割を行う。

### データ構造分割法(データの構造に注目して分割)

いわゆるジャクソン法であり、「入出力データの構造からプログラムの構造を決定していく方式」である。


<img width="583" alt="ジャクソン法.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/271543/5b358b08-7f95-7f47-c75e-12989c119e07.png">

### 共通機能分割

- メリット：コード量の削減。修正範囲の最小化。


## モジュール分割の評価

評価観点。

- 独立性
    - モジュール間結合度が低いほど良い
    - 「モジュール間結合度」について...
        - 共通結合...複数のモジュール間であるデータ領域を参照している結合
        - 外部結合...外部参照可能であると宣言されたデータ領域を他のモジュールが直接参照する結合
        - 制御結合...あるモジュールが他のモジュールを呼び出すとき、制御のためのフラグやパラメータを渡すような結合。
        - <font color="Red">スタンプ結合...モジュール間で共有のデータ構造データを扱う。データ構造が変わった場合は両者に変更が及び、また一方には必要のないメンバデータを含む場合がある。</font>
   
- 汎用性
- <font color="Red">大きさ</font>
    - 人間の認知範囲を反映したコード量。目安は100行程度。

<img width="542" alt="module強度.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/271543/d2553266-3973-4ed6-ddd3-fca7a5b0688e.png">


- モジュール強度
    - 1つのモジュール内の機能間の関係性をモジュール強度という
    - <font color="Red">モジュール強度が弱いとき、さらなるモジュール分割を吟味する必要がある</font>
        - ①暗号的強度...機能の関連がない場合であり、互いに関係ない複数の機能を実行している。
        - ②論理的強度...制御変数により機能を選択するようなモジュールでは、機能を変更すると、呼び出し側のモジュールにも変更が波及する。
        - ③時間的強度
        - ④手順的強度...各機能の起動んい順序関係がある
        - ⑤連絡的強度...各機能の起動んい順序関係があり、かつ各機能が共通のデータを参照する
        

# プログラミング

(構造化)プログラミングは、「逐次」「(条件)選択」「繰り返し」の3つの制御構造を使って記述できる。

## ポイント

- コードを書く前に、コメント等の疑似コードで問題を解く。他にはフローチャートなどがある。(要はいきないコードを書かない)
    - そして、そのロジックに従ってコード化していく


# テストと保守

## テスト環境

<img width="342" alt="テスト環境.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/271543/8dc0ba81-1b95-7bf7-2e96-a68c2d83b8ed.png">

## テスト戦略

- トップダウンテスト:モジュール構成の上位モジュールからテストを実施し、順次下位モジュールを加えながらテストしていく
    - スタブを作る必要がある
    - 上位モジュールの重大な欠陥を先に発見できる
    - 下位モジュールを並列してテストすることが難しい
    
- ボトムアップテスト:モジュール構成の下位モジュールからテストを実施し、順次上位モジュールを加えながらテストしていく
    - ドライバを作る必要がある
    - 平行したテスト実施が可能
    - アーキテクチャやインターフェースに関する重大な結果がテスト最終段階近くにならないと見つからない
    

## テストケース設計技法

- ブラックボックステスト
    - ありうる入力の組み合わせと、その入力に対する出力を選択する方法
    - 具体的な設計方法
        - 同値分割(無効な同値クラスも含める)
        - 限界値分析
        - 状態ベース仕様に基づくテストケース設計
- ホワイトボックステスト
    - プログラム構造を網羅するようにテストケースを見出す方法
        - 命令網羅テスト
        - 分岐網羅テスト
            - プログラムの条件分岐が全て実行されているか
- ランダムテスト
    - コンピュータによって容易に多数のテストケースを作り出せ、思いもよらぬテストケースを作れるのが利点。ただ、プログラム構造における網羅率が低いのが弱点。
- 妥当性確認テスト
    - ユーザ要求の非機能的な側面を満たしているかのテスト


- 妥当性テスト(非機能テスト)...汎用的テスト手法があるわけではないので、経験等をもとに適宜柔軟な手法を実施する必要がある
    - ネットワーク(レスポンス、安定性、アクセス増加)
    - 障害対応(DB<font color="Red">、回復テスト</font>)
    - 容量(DB)
    - <font color="Red">セキュリティ(データ保全)</font>
    - <font color="Red">人為的ミスの配慮 </font>
    - <font color="Red">性能テスト(処理時間) </font>
    - <font color="Red">互換性テスト(変更手順の妥当性含む) </font>
    - <font color="Red">設置手順テスト(手順の妥当性) </font>


- テスト妥当性評価(これまでのテスト技法を評価する方法)
    - 1.網羅率
        - 達成基準は100%
            - 仕様に基づいての評価
                - 機能軸
                - システム状態軸
                - 入力全パターン(同値クラスを活用した上の)
            - プログラムの基づいての評価
                - 制御構造軸
                    - 全命令を網羅する命令網羅
                    - 全ての条件式を網羅する条件網羅
                    - etc
                - データフロー軸
                    - 変数値のプログラム内での変更パターンの組み合わせを追跡するもの
        - <font color="Red">既にテスト済のテストケースを別の網羅度で評価することで、未発見のテストケースを発見でき、多くの欠陥を発見できる </font>
    - 2.欠陥除去基準
        - 欠陥発生モデル(欠陥検出累積数の成長曲線モデル=コンペルツ曲線)をもとに、モデル予測値と大きくかけ離れていないかを評価
    - 3.運用的基準
        - <font color="Red">信頼性工学の分野では、被検査対象に欠陥が発生するまでの平均時間であるMTBFをもとに、信頼性を評価する。</font>
        - この基準はシステムテストLvで適用され、ランダムテストと併用される(普及していないのは、ランダムテストを自動で行う環境が必要となってしまうため)


##保守

### 定期作業の継続

### 新バグの対応(解析・修正依頼)
#### 問題と対策
- 他のサービスとの相互関係による予期しないバグが発生
    - 対策：過剰テストはコスト的にダメなので、サービスの主要同線は「独立性を高めて」、サービスの本質機能は担保するよう設計・テストする？ 

- <font color="Red">回収したモジュールが他に影響を及ぼす可能性(デグレッション)がある
    - 解決策：回帰テストの実施と、回帰テストを想定してテストパターンやテストデータを蓄積しておく(可能なら自動化したい)</font>

### <font color="Red">予防のための保守</font>
####問題と解決策
- 将来、起こりうる問題(HW変化、インターフェースの変化、機能拡張)を想定して設計する(例えば、独立性を高める、オブジェクト指向など)

### オペレーションサポート

### 次期機能改善のための問題把握(&改善)
#### 問題と対策
- 追加機能を行うときに、運用フェーズではシステム全般を把握して、影響度や修正範囲を把握している人材がいない可能性が高い
    - 解決策：本来、属人化を避けるために、だれでもできるようドキュメントを残すべき？


- サービスイン前と違い、運用後の修正は、与えらえる期間が短い
    -　解決策：迅速に原因解明できること、試験を用意に実施できる環境の2点が必要？


- OSバージョンの違いや、ハードウェアの交換
    - ハードウェアやミドルウェアの違いを吸収するような設計が望ましい(仮想化。テキストベースによる環境設定など)

#オブジェクト指向

- オブジェクト指向
    - 定義：サービスとは、オブジェクトとオブジェクトとの間のメッセージで実現されるイメージ
    - <font color="Red">メリット：保守性が高い
        - 高い理由は、カプセル化と継承、ポリフォーリズム</font>
            - カプセル化：
                - データと操作が1オブジェクト内に収まっていて、隠蔽されている
                - オブジェクト内のデータはメッセージインターフェースにより守られており、モジュール性(独立性)が高まる
                - 「クラスとインスタンス」はカプセル化を実現する手段であり、クラスは同じ属性のグループの記述、インスタンスは具現化したオブジェクトを示す。
            
            - 継承：
                - オブジェクトの再利用性が高まる(コード量が減る=改修範囲が狭まる)

         
            - ポリフォーリズム
                - <font color="Red">本来型のあるプログラミング言語において、型に束縛されずにアルゴリズムを再離床するための機能を指す言葉。</font>(要はアルゴリズムの再利用)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/271543/9d456bcd-4f6c-2b9a-d8bd-a5fdf9fd1351.png)

## オブジェクト指向によるものづくり

- オブジェクト指向分析→オブジェクト設計→オブジェクト指向プログラミング

### オブジェクト指向分析

- 要求分析時には以下が主に必要
    - 問題の理解
    - 問題の解決方法の検討

- <font color='red'> オブジェクト指向分析は、上記のような要求分析にオブジェクト指向のモデリングを適用することで、問題の理解と解の仕様化をスムーズになることを狙ったもの</font>
        - メリット：
            - モデリングは実世界との対応関係がつきやすいオブジェクトを中心にシステムを考えるので、ユーザー要求を素直に表現しやすい、かつ仕様を形式的に記述できる(ex.UML図なｄｌ)
            - また、上記により仕様の誤りなどを発見・修正しやすい
           
## UML

- クラス図
    - オブジェクトの記述(定義)。データと機能を示す。
    - <font color = "red">システムをデータ視点で記述。</font>
    
- ユースケース図
    -  業務/システムレベルの大まかな流れ
    -  <font color = "red">システムをユーザー視点で記述。</font>
   
- シーケンス図
    - ユースケースの記述粒度をオブジェクトレベルに落として物。オブジェクトの変化(データ変化、機能発動)の流れを示す
   
- <font color = "red">ステートマシン図</font>
    - オブジェクトを中心にそえ、そのオブジェクトが変化しうる状態の全パターン
    - <font color = "red">システムを中心にそえ、そのふるまいの視点から記述。</font>

### クラス図

![image.png](https://qiita-image-store.s3.amazonaws.com/0/271543/498ed2f6-f2b5-af41-564d-c83bdedfaa7e.png)

- 多重継承による「特殊化」はさけ、別の属性を設けるなどの対策を取ることが望ましい
- なぜ多重継承はダメ？
    - 継承しているクラスに改修が入ったら、修正等がめんどいから？

### ユースケース図

- アクタが発するイベントを契機として始まるサービスを、アクタとシステム間のやり取りとして自然言語で表したもの。
    - 必要な情報
        - 前提条件
        - 利用手順
        - output (+α<font color = "red">事後条件</font>)


### シーケンス図

### <font color = "red">オブジェクト類型化</font>

- オブジェクト指向分析を行う上で、オブジェクトの見つけ方が最も難しく、分析の良しあしがそこに集約されるといわれる
    - そこで、オブジェクトを見つけるための指針として、jacobsonの類型化方法を基本とおいた見つけ方について述べる



#### <font color = "red">jacobsonを基本としたオブジェクト類型化 </font>

この類型化では、オブジェクトを「アクタ、端末、監視・制御対象、情報の塊、コントローラ」の順に探すことを推奨している。

- アクタ：システム動作を始める最初のイベントを起こす役。システム制御対象ではないので、属性は持たない
- 端末：アクタがシステムと情報のやり取りを行う端末。
- 監視・制御対象：監視・制御すべき実世界オブジェクトをその目的に合わせて抽象化したもの。(ex.実世界の車を制御するなら、「車」という抽象化されたオブジェクトをシステム内に用意し、システムからの情報アクセスを用意にする)
- 情報の塊：姿形はないが、概念あるいは社会的実体として認識される名詞(ex.注文や口座)のこと。
- コントローラ：システムが持つべき機能は通常オブジェクトの持つ操作操作として割り当てられる。しかし、機能の中には上記オブジェクトのどれにも自然と割り当てられない場合がある(ex.エレベータの管理機能、コンパイラによる最適化機能)。こうした機能に対しては、その機能を果たすことを使命とするオブジェクトを新たにコントローラオブジェクトとして設ける。このように機能のオブジェクト化を図る際に、カプセル化を意識することも重要(最適化を行う機能は「オプティマイザ」オブジェクトと凡化することで、再利用性が高まる)

### モデルの洗練化

- クラス図とシーケンス図などを突き合わせて、モデルを洗練していく過程で基準を提供する<font color = "red">「CRCカードと呼ばれるレビュー法」</font>を説明する
    - やり方：クラス名とその役割、責任、協力クラスを記述し、レビューする
    - レビューの主な観点は以下
        - クラス名から役割が想像できるか
        - 必要な協力クラスが網羅されているか、同時に役割がかぶっていないか
        - クラス名がHWなど実オブジェクトに依存していないか

![image.png](https://qiita-image-store.s3.amazonaws.com/0/271543/c87b0898-e538-8e10-febc-ff42f0a54f5f.png)


## オブジェクト指向設計

- 初期モデル

![image.png](https://qiita-image-store.s3.amazonaws.com/0/271543/81b14565-fbc3-a4f8-b582-0ba03c4bba47.png)

- 初期モデルの問題点
    - <font color = "red">エディタから見て、複合描画画像と描画画像を分けて管理しなければならない</font>
    - <font color = "red">複合描画を構成要素として複合描画を、このモデルでは構成できない</font>


- モデル修正

![image.png](https://qiita-image-store.s3.amazonaws.com/0/271543/8f2c637a-9a29-e92d-d1d7-38234bfde66c.png)

## オブジェクト指向プログラミング

カプセル化、継承、ポリフォーリズムを軸に述べていく

### カプセル化


## 継承
良い継承とは、「AはBである」という表現が自然であること

## ポリフォーリズム

C++では、親クラスで仮想関数宣言されたメンバ関数を、子孫クラスの中で再定義することで、具象クラスに動的に応じて呼び出す関数を変えることができる


#ソフトウェア再利用