【コードあり】ストラテジーパターンのC++版サンプルコード

今回はデザインパターンのストラテジーパターンのサンプルコードを作成しました。
記事の作成に当たってインプットには以下の書籍やサイトを使って勉強しました。
間違い等あればコメントしてもらえると対応します。
目次
ストラテジーパターンの概要
ストラテジーパターンは、アルゴリズムを実行するためのインターフェースを定義し、複数のアルゴリズムを定義し、それらを交換可能にするデザインパターンです。
構造はrefactoring.guruの図がわかりやすいのでそれ見て下さい。
c++ のサンプルコード
例として、さまざまな支払い方法(クレジットカード、銀行振込、PayPalなど)を切り替えられるプログラムを書いてみました。
インターフェース(PaymentStrategy.h)
クレジットカードクラス、PayPolクラス、銀行振込クラスの共通処理であるpay()を実装しています。
#include <iostream>
class PaymentStrategy {
public:
    virtual ~PaymentStrategy() {}
    virtual void pay(double amount) const = 0;
};クレジットカードクラス(PaymentStrategy.h)
PaymentStrategyクラスを継承してpay関数をオーバーライドしています。
#include "PaymentStrategy.h"
class CreditCardPayment : public PaymentStrategy {
public:
    void pay(double amount) const override {
        std::cout << "Paying " << amount << " dollars via Credit Card." << std::endl;
    }
};PayPolクラス(PayPalPayment.h)
pay関数をクレジットカードクラスとは異なる内容にしています。
#include "PaymentStrategy.h"
class PayPalPayment : public PaymentStrategy {
public:
    void pay(double amount) const override {
        std::cout << "Paying " << amount << " dollars via PayPal." << std::endl;
    }
};銀行振込クラス(BankTransferPayment.h)
#include "PaymentStrategy.h"
class BankTransferPayment : public PaymentStrategy {
public:
    void pay(double amount) const override {
        std::cout << "Paying " << amount << " dollars via Bank Transfer." << std::endl;
    }
};Main関数(main.cpp)
ショッピングカートクラスがContextに当たります。コンストラクタとsetPaymentStrategy関数でクレジットカードとPayPolと銀行振り込みを切り替えられるようにし、checkout関数を実行することでセットしたクラスのpay関数が実行されます。
pay関数の中身はクラスによって異なるため、クライアント(main関数)は同じcheckout関数を実行するだけですが、実行される内容はその時にセットされているクラスによって異なる動作をします。
#include "PayPalPayment.h"
#include "CreditCardPayment.h"
#include "BankTransferPayment.h"
// ショッピングカートクラス
// 引数でPaymentStrategy型のオブジェクトを受け取る
class ShoppingCart {
private:
    PaymentStrategy* paymentStrategy;
public:
    ShoppingCart(PaymentStrategy* strategy) : paymentStrategy(strategy) {}
    void setPaymentStrategy(PaymentStrategy* strategy) {
        paymentStrategy = strategy;
    }
    void checkout(double amount) const {
        paymentStrategy->pay(amount);
    }
};
int main(void) {
    // 支払い方法の選択
    PaymentStrategy* creditCard = new CreditCardPayment();
    PaymentStrategy* bankTransfer = new BankTransferPayment();
    PaymentStrategy* payPal = new PayPalPayment();
    // ショッピングカートの作成
    ShoppingCart cart(creditCard);
    // 商品の合計金額
    double totalAmount = 100.0;
    // クレジットカードで支払い
    std::cout << "Using Credit Card:" << std::endl;
    cart.checkout(totalAmount);
    // 支払い方法の変更
    cart.setPaymentStrategy(bankTransfer);
    // 銀行振込で支払い
    std::cout << "\nUsing Bank Transfer:" << std::endl;
    cart.checkout(totalAmount);
    // 支払い方法の変更
    cart.setPaymentStrategy(payPal);
    // PayPalで支払い
    std::cout << "\nUsing PayPal:" << std::endl;
    cart.checkout(totalAmount);
    // メモリの解放
    delete creditCard;
    delete bankTransfer;
    delete payPal;
    return 0;
}サンプルコードの実行結果
実行結果は以下のようになります。
Using Credit Card:
Paying 100 dollars via Credit Card.
Using Bank Transfer:
Paying 100 dollars via Bank Transfer.
Using PayPal:
Paying 100 dollars via PayPal.



