design_pattern_compound

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值