design_pattern_compound

来源:互联网 发布:头颅移植手术 知乎 编辑:程序博客网 时间:2024/06/02 04:29

This post implements compound pattern in <Head First Design Pattern>.  The examples are based on Duck classes.

class Quackable {public:    virtual void quack() = 0;};class MallardDuck : public Quackable {public:    void quack(){        std::cout << "Quack" << std::endl;    }};class ReadheadDuck : public Quackable {public:    void quack(){        std::cout << "Quack" << std::endl;    }};class DuckCall : public Quackable {public:    void quack(){        std::cout << "Kwak" << std::endl;    }};class RubberDuck : public Quackable {public:    void quack(){        std::cout << "Squeak" << std::endl;    }};
First of all, the adapter pattern, we have a goose, therefore, we need a GooseAdapter:

class Goose {public:    void honk(){        std::cout << "Honk" << std::endl;    }};class GooseAdapter : public Quackable {private:    Goose* goose;public:    GooseAdapter(Goose* goose_):goose(goose_){}    void quack(){        goose->honk();    }    ~GooseAdapter(){        delete goose;        goose = NULL;    }};

Then, the decorator pattern, we need to count the number of quack, pay attention to the static variable and how it is initialized in main function.

class QuackCounter : public Quackable {private:    Quackable* duck;    static int numquack;public:    QuackCounter(Quackable* duck_):duck(duck_){};    ~QuackCounter(){        delete duck;        duck = NULL;    }    void quack(){        duck->quack();        numquack++;    }    static int getQuack(){        return numquack;    }};
The main function is

#include <iostream>#include <./duck.hpp>int QuackCounter::numquack = 0;int main(){    Quackable* mallarDuck = new QuackCounter(new MallardDuck());    Quackable* readheadDuck = new QuackCounter(new ReadheadDuck());    Goose* goose = new Goose();    GooseAdapter * gduck = new GooseAdapter(goose);    Quackable* ggduck = new QuackCounter(gduck);    mallarDuck->quack();    readheadDuck->quack();    ggduck->quack();    std::cout << QuackCounter::getQuack() << std::endl;    return 0;}

Then we want to simplify client operation by using factory method to create ducks

class DuckFacotry {public:    virtual Quackable* createMallardDuck() = 0;    virtual Quackable* createRedheadDuck() = 0;    virtual Quackable* createDuckCall() = 0;    virtual Quackable* createRubberDuck() = 0;};class PureDuckFactory : public DuckFacotry {public:    virtual Quackable* createMallardDuck(){ return new MallardDuck(); }    virtual Quackable* createRedheadDuck(){ return new RedheadDuck(); }    virtual Quackable* createDuckCall(){ return new DuckCall(); }    virtual Quackable* createRubberDuck(){ return new RubberDuck(); }};class CountingDuckFactory : public DuckFacotry {public:    virtual Quackable* createMallardDuck(){        return new QuackCounter(new MallardDuck());    }    virtual Quackable* createRedheadDuck(){        return new QuackCounter(new RedheadDuck());    }    virtual Quackable* createDuckCall(){        return new QuackCounter(new DuckCall());    }    virtual Quackable* createRubberDuck(){        return new QuackCounter(new RubberDuck());    }};

We could create ducks with/without counting ability in a uniform interface. The main function becomes

#include <iostream>#include <./duck.hpp>#include <./duckfactory.hpp>int QuackCounter::numquack = 0;int main(){    DuckFacotry* df = new CountingDuckFactory();    Quackable* mallardDuck = df->createMallardDuck();    Quackable* readheadDuck = df->createRedheadDuck();    Goose* goose = new Goose();    GooseAdapter * gduck = new GooseAdapter(goose);    Quackable* ggduck = new QuackCounter(gduck);    mallardDuck->quack();    readheadDuck->quack();    ggduck->quack();    std::cout << QuackCounter::getQuack() << std::endl;    return 0;}
The result is the same




0 0
原创粉丝点击