0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

c言語の経験から見たオブジェクト指向でのV字モデル開発

0
Posted at

【保存版】C言語の経験から学ぶオブジェクト指向とV字モデル開発の対応付け

本書は、C言語(構造化手法)における「ファイル・関数単位」の設計経験をベースに、オブジェクト指向(C++)の「クラス・メソッド単位」の設計、およびV字モデル開発への対応付けを体系的に整理したマスタードキュメントです。


1. 開発手法による設計アプローチの決定的な違い

C言語(機能中心)とオブジェクト指向(モノ中心)では、基本設計と詳細設計で決定する「パーツ」の捉え方が異なります。

設計フェーズ C言語(機能・ファイル中心) オブジェクト指向(モノ・クラス中心)
基本設計 「機能単位のファイル」の決定
・システムを構成する機能モジュール(order.c, user.c など)を切り出す。
・大枠のデータ構造体(struct)を決める。
「モノ単位のクラス(大別・種類)」の決定
・システムに登場する概念(Customer, Order など)を洗い出す。
・共通ルールとなる親クラス(抽象クラス)を定義する。
詳細設計 「ファイル内の関数」の決定
・ファイル内に必要な具体的な関数(calc_tax(), save_order() など)を洗い出す。
・関数内の処理フローを設計する。
「クラス内のメソッドと子クラスの処理」の決定
・親クラスを継承した「子クラス(サブクラス)」を具体化する。
・各クラス内のメソッド(処理・ロジック)を確定させる。

2. オブジェクト指向×C++×V字モデル完全対応

オブジェクト指向の4大概念(抽象化・カプセル化・継承・ポリモーフィズム)が、V字モデルの左側(設計・実装)から右側(テスト)へどのように1対1で対応するかを網羅した一覧です。

V字モデルのフェーズ 設計・実装での活動(左側〜底部) オブジェクト指向の概念とC++での表現 対応するテストフェーズ(右側)での検証内容
要件定義 ユーザーの「どうしたいか」を分析し、システムの本質を抜き出す。 【抽象化】
・現実世界の登場人物や業務概念をユースケース図やドメインモデルに落とし込む。
システムテスト / 運用テスト
・ユーザーの要求通りにシステム全体が機能するかを検証。
基本設計 パーツの大別と種類の決定。
共通ルール(親枠)を決める。
【抽象化】【カプセル化】
・共通窓口を持つ抽象クラス(class Character)の定義
・データ隠蔽のルール決定
結合テスト(パッケージ結合)
・異なるサブシステム間や、オブジェクトの共通窓口(関数)を介した連携が正しく動くかを検証。
詳細設計 子クラス(種類)の具体的な内部処理や、オブジェクト同士の連携を設計する。 【継承】【ポリモーフィズム】
・親から個別仕様への分岐(Warrior, Wizard)
・シーケンス図によるメッセージ連携の設計
単体テスト(クラス・モジュール結合)
・【ポリモーフィズムの検証】
・親のポインタから関数を呼んだ際、実体(子クラス)に応じて正しく処理が切り替わるかを検証。
実装 詳細設計をプログラムに翻訳する。 【C++での具体化】
・private/public による隠蔽
・: public による継承
・virtual/override による上書き
単体テスト(メソッド単位)
・【カプセル化の検証】
・各メソッド単体の入出力検証。
・privateなデータが不正に書き換えられないかの検証。

3. C++コードによるオブジェクト指向4大概念の実装例

オブジェクト指向の核心となる4つの概念は、C++において以下のように記述されます。

#include <iostream>
#include <string>

// =========================================================================
// ④ 抽象化(Abstraction): 共通の本質だけを抜き出した「概念(大枠)」の設計
// =========================================================================
class Character {
// ① カプセル化(Encapsulation): 外部から直接データを触らせず、安全な窓口だけを公開
private:
    std::string name;
    int hp;

public:
    Character(std::string n, int h) : name(n), hp(h) {}

    // カプセル化されたデータにアクセスするための公開窓口(メンバ関数)
    std::string getName() const { return name; }
    int getHp() const { return hp; }

    // ③ ポリモーフィズムのための「純粋仮想関数」
    // 基本設計(親)では「攻撃できる」という枠組みだけを決め、中身の処理は詳細設計(子)に強制する
    virtual void attack() = 0; 

    virtual ~Character() {} // 仮想デストラクタ
};

// =========================================================================
// ② 継承(Inheritance): 親(Character)の資産を引き継ぎ、独自の「種類」を作る
// =========================================================================
class Warrior : public Character {
public:
    Warrior(std::string n, int h) : Character(n, h) {}

    // ③ ポリモーフィズム(Polymorphism): 親の attack を子クラス専用の処理に「上書き」
    // 詳細設計で「戦士の具体的な処理ロジック」を作り込む部分
    void attack() override {
        std::cout << getName() << " は大剣で豪快に斬りつけた!" << std::endl;
    }
};

class Wizard : public Character {
public:
    Wizard(std::string n, int h) : Character(n, h) {}

    // 詳細設計で「魔法使いの具体的な処理ロジック」を作り込む部分
    void attack() override {
        std::cout << getName() << " は呪文を唱え、炎を放った!" << std::endl;
    }
};

// =========================================================================
// メイン処理(検証)
// =========================================================================
int main() {
    // 結合テストの視点:異なる子クラスを「親クラス(Character)」として一括で扱う
    Character* party[2];
    party[0] = new Warrior("アルス", 150);
    party[1] = new Wizard("マローネ", 80);

    // ポリモーフィズムの真骨頂:同じ「attack()」の呼び出しで、実体に応じた個別の処理が走る
    for (int i = 0; i < 2; ++i) {
        party[i]->attack(); 
    }

    delete party[0]; delete party[1];
    return 0;
}

4. オブジェクト指向を導入する開発プロセス上のメリット

  1. 高いトレーサビリティ(追跡可能性)
    要件定義の「アクター」が基本設計の「親クラス」になり、詳細設計の「子クラス」へと直結し、そのまま実装コードの class になります。V字モデルの左から右(テスト)へ移る際、「何をテストすればよいか」の迷いがなくなります。
  2. バグの局所化(カプセル化の効果)
    データと関数がクラス内に閉じ込められている(private)ため、単体テストでデータ不正が見つかった際、原因の調査範囲はそのクラスの内部だけに限定され、C言語のように「どこかのファイルがグローバル変数を書き換えていた」という迷宮入りを防げます。
  3. 拡張時の安全設計(継承・ポリモーフィズムの効果)
    新しい「種類(子クラス)」を追加する際、既存のファイルや関数(親クラス側)に if/switch 文を追加する必要がありません。新しい子クラスのファイルを1つ独立して作成(差分開発)するだけで済むため、既存機能へのデグレード(先祖返り・バグ混入)を完全に防げます。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?