HiroLab

プログラミングに関する情報発信サイト。

C++

【C++】Day 27:デザインパターン「構造型パターン」

投稿日:

Day 27では、デザインパターンのうち「構造型パターン」について学習します。

構造型パターンは、クラスやオブジェクトの構造を改良するためのパターンです。主な構造型パターンには、アダプタ、デコレータ、コンポジット、ブリッジ、ファサードなどがあります。

以下に構造型パターンの主な内容と、例題、演習問題を提示します。

 

構造型パターンの主な内容:

1. アダプタパターン:
– アダプタパターンは、既存のクラスのインターフェースを別のインターフェースに変換するパターンです。
– 互換性のないクラスを連携させることができます。

 

2. デコレータパターン:
– デコレータパターンは、オブジェクトに対して動的に機能を追加するパターンです。
– サブクラスを作成することなく、機能を追加できます。

 

3. コンポジットパターン:
– コンポジットパターンは、オブジェクトの階層構造を木構造で表現するパターンです。
– 個々のオブジェクトと合成オブジェクトを同じように扱えます。

 

4. ブリッジパターン:
– ブリッジパターンは、抽象と実装を分離してそれぞれ独立に拡張できるパターンです。
– 機能と実装を柔軟に組み合わせることができます。

 

5. ファサードパターン:
– ファサードパターンは、複雑なサブシステムのインターフェースを単純化するパターンです。
– クライアントが使いやすいインターフェースを提供します。

 

例題:

デコレータパターンの例として、コーヒーを注文して様々なトッピングを追加するプログラムを考えてみましょう。

#include <iostream>
#include <string>

// コーヒーの抽象クラス
class Coffee {
public:
virtual std::string getDescription() const = 0;
virtual double cost() const = 0;
};

// ベースのコーヒー
class SimpleCoffee : public Coffee {
public:
std::string getDescription() const override {
return "Simple Coffee";
}

double cost() const override {
return 100.0;
}
};

// コーヒーのトッピングを表すデコレータ
class CoffeeDecorator : public Coffee {
protected:
Coffee* coffee;

public:
CoffeeDecorator(Coffee* coffee) : coffee(coffee) {}

std::string getDescription() const override {
return coffee->getDescription();
}

double cost() const override {
return coffee->cost();
}
};

// ミルクのトッピング
class MilkDecorator : public CoffeeDecorator {
public:
MilkDecorator(Coffee* coffee) : CoffeeDecorator(coffee) {}

std::string getDescription() const override {
return coffee->getDescription() + ", Milk";
}

double cost() const override {
return coffee->cost() + 50.0;
}
};

// シロップのトッピング
class SyrupDecorator : public CoffeeDecorator {
public:
SyrupDecorator(Coffee* coffee) : CoffeeDecorator(coffee) {}

std::string getDescription() const override {
return coffee->getDescription() + ", Syrup";
}

double cost() const override {
return coffee->cost() + 70.0;
}
};

int main() {
Coffee* coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee);
coffee = new SyrupDecorator(coffee);

std::cout << "Description: " << coffee->getDescription() << std::endl;
std::cout << "Cost: " << coffee->cost() << " yen" << std::endl;

delete coffee;

return 0;
}

 

演習問題:

1. コンポジットパターンを使って、ファイルシステムの階層構造を表現するプログラムを作成してください。ディレクトリとファイルを同じように扱えるようにしてください。

2. ファサードパターンを使って、オーディオプレーヤーの制御を行うプログラムを作成してください。再生、停止、次の曲へのスキップなどの機能を提供するファサードを作成し、クライアントがシンプルなインターフェースで操作できるようにしてください。

これらの例題と演習問題を解くことで、構造型パターンの理解と実践ができます。問題を解いたら、各パターンが正しく動作しているかどうかを確認してみてください。

-C++
-, ,

執筆者:


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

関連記事

【C++】Day 29:「セキュリティと暗号化」

Day 29では、「セキュリティと暗号化」について学習します。 セキュリティと暗号化は、情報を保護するための重要な概念です。データの機密性、完全性、可用性を確保するために、データの暗号化、ハッシュ化、 …

【C++】Day 16:C++のラムダ式とSTLアルゴリズム

Day 16では、C++のラムダ式とSTLアルゴリズムについて学習します。 ラムダ式は、簡単な関数をインラインで定義する方法であり、STLアルゴリズムは標準ライブラリのアルゴリズム関数です。 以下にそ …

【C++】Day 24:デバッグとテスト

Day 24では、デバッグとテストについて学習します。 プログラムを書く際には、バグを見つけて修正するデバッグや、プログラムが正しく動作することを確認するテストが重要です。 以下にデバッグとテストに関 …

【C++】Day 4:制御文の一つである条件分岐(if文、else文、else if文)について

Day 4では、制御文の一つである条件分岐(if文、else文、else if文)について学習します。 条件分岐は、特定の条件に基づいてプログラムのフローを制御するために使用されます。 条件が真(tr …

【C++】Day 25:パフォーマンスと最適化

Day 25では、パフォーマンスと最適化について学習します。 プログラムのパフォーマンスは、実行速度やメモリ使用量などの面での良し悪しを指します。最適化は、プログラムのパフォーマンスを向上させるために …