Naruto
1/18/2015 - 1:00 PM

compare Strategy pattern implementation of c++98 and c++11 (reference: http://isocpp.org/blog/2013/10/patterns )

compare Strategy pattern implementation of c98 and c11 (reference: http://isocpp.org/blog/2013/10/patterns )

// c++ -std=c++11 -Wall ./strategy_cpp11.cpp  -o strategy_cpp11
#include <iostream>
#include <vector>
#include <functional>

class Recipes {
public:
    static void brewCoffee() { std::cout << "dripping Coffee through filter\n"; }
    static void brewTea() { std::cout << "steeping Tea\n"; }

    static int amountWaterMl(int ml) { return ml; }

};

class CaffeineBeverage {
public:
    CaffeineBeverage(std::function<int()> amountWaterMl, std::function<void()> brew)
        : _amountWaterMl(amountWaterMl)
        , _brew(brew)
          {}

    void prepare() {
        boilWater(_amountWaterMl());
        _brew();
        pourInCup();
    }

private:
    void boilWater(int ml) { std::cout << "boiling " << ml << " water\n"; }
    void pourInCup() { std::cout << "pour in cup\n"; }
    std::function<int()> _amountWaterMl;
    std::function<void()> _brew;
};

int main() {
    CaffeineBeverage coffee(
        [] { return Recipes::amountWaterMl(150); }, &Recipes::brewCoffee);
    CaffeineBeverage tea(
        [] { return Recipes::amountWaterMl(200); }, &Recipes::brewTea);

    using Beverages = std::vector<CaffeineBeverage*>;
    Beverages beverages;

    beverages.push_back(&coffee);
    beverages.push_back(&tea);

    for(auto &beverage : beverages) {
        beverage->prepare();
    }
}
// c++ -Wall ./strategy_cpp98.cpp  -o strategy_cpp98
#include <iostream>
#include <vector>

class Recipe {
public:
    virtual void brew() = 0;

    virtual int amountWaterMl() = 0;

};

class CoffeeRecipe : public Recipe {
public:
    CoffeeRecipe(int water)
        : Recipe()
        , _amountWaterMl(water)
        {}

    virtual void brew() { std::cout << "dripping Coffee through filter\n"; }

    virtual int amountWaterMl()  { return _amountWaterMl; }

private:
    int _amountWaterMl;
};

class TeaRecipe : public Recipe {
public:
    TeaRecipe(int water)
        : Recipe()
        , _amountWaterMl(water)
        {}

    virtual void brew() { std::cout << "steeping Tea\n"; }

    virtual int amountWaterMl() { return _amountWaterMl; }

private:
    int _amountWaterMl;
};


class CaffeineBeverage {
public:
    CaffeineBeverage(Recipe *recipe)
        : _recipe(recipe)
          {}

    void prepare() {
        boilWater(_recipe->amountWaterMl());
        _recipe->brew();
        pourInCup();
    }

private:
    void boilWater(int ml) { std::cout << "boiling " << ml << " water\n"; }
    void pourInCup() { std::cout << "pour in cup\n"; }
    Recipe *_recipe;
};

int main() {
    CoffeeRecipe coffeeRecipe(150);
    TeaRecipe teaRecipe(200);
    CaffeineBeverage coffee(&coffeeRecipe);
    CaffeineBeverage tea(&teaRecipe);

    typedef std::vector<CaffeineBeverage*> Beverages;
    Beverages beverages;

    beverages.push_back(&coffee);
    beverages.push_back(&tea);

    for(Beverages::iterator it(beverages.begin()); it != beverages.end(); ++it) {
        (*it)->prepare();
    }
}