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 17:例外安全性とエラーハンドリング

Day 17では、例外安全性とエラーハンドリングについて学習します。 C++では、プログラムが例外(予期しないエラー状態)に遭遇した際に、そのエラーを適切に処理することが重要です。例外安全性は、プログ …

【C++】Day 2:変数とデータ型について

Day 2では、変数とデータ型について学習します。 変数はデータを格納するためのメモリ上の領域であり、データ型はその変数が保持できるデータの種類を指定します。 C++にはいくつかの基本的なデータ型があ …

【C++】Day 22:ネットワークプログラミングにおけるソケットとプロトコル

Day 22では、ネットワークプログラミングにおけるソケットとプロトコルについて学習します。 ソケットは、ネットワーク通信を行うためのプログラムインターフェースであり、プロトコルは通信のルールや方法を …

【C++】Day 19:マルチスレッドプログラミングにおける同期と通信の重要性

Day 19では、マルチスレッドプログラミングにおける同期と通信の重要性について学習します。 マルチスレッドプログラムでは複数のスレッドが同時に動作するため、スレッド同士が競合状態になる可能性がありま …

【C++】Day 30:C++の応用と展望

Day 30では、「C++の応用と展望」について学習します。 C++は非常にパワフルで柔軟なプログラミング言語であり、さまざまな応用分野で使用されています。この日は、C++の応用領域や将来の展望につい …