每天一个设计模式(C++) -Day1-策略模式-Strategy Pattern

策略模式的核心

定义算法簇,分别封装,让他们之间可以相互替换。最终使得算法可以独立于使用算法的客户。(从书上抄来的,看不懂不要 紧,继续往下看,看完全文再返回来你就理解了)

使用策略模式的原因

假设我们要写一个游戏,游戏里面有很多种类的鸭子,学过OO设计的我们一定会设计一个抽象鸭子类Duck,然后写一系列的具体的鸭子类型来继承Duck,像这样:

这里所有的鸭子都会游泳,所有的鸭子都会quack叫,但是由于不同的鸭子外形不同,所以在超类中我们定义display为虚函数,在子类中重载他。

可是当我们有一个这样的新的需求的时候:我们现在需要在游戏中加入一种橡皮鸭,橡皮鸭不会quack叫而是捏起来squeak这样叫的,或者我们要加入一个木头鸭子,他既不会叫也不会游泳(因为他会沉下去而橡皮鸭不会)。

这时候我们要怎么办呐,你可能会想到一个办法:在橡皮鸭和木头鸭子中重载quack方法,让这个方法为空 do nothing,但是要是我们又需要加入一大堆的玩具鸭子呐?他们有的会叫有的不会叫。

分开会变化的部分和不会变化的部分

这里我们用到一个设计原则:我们要找出应用中可能需要改变之处,把他们独立出来,不要和那些不需要变化的代码混淆在一起。

基于这个原则我们要把鸭子的各种行为独立出来变成一个类,这样我们就可以独立的更新和修改这些行为

针对变化的部分

我们要用到第二个设计原则:针对接口编程,而不是针对实现编程

为了进一步封装使得鸭子的实现不需要考虑方法的细节,我们要把鸭子的行为分开放到不同的类中,然后让具体的鸭子来使用这些不同的类

上图(鸭子叫的方法):

我们通过这种方法重新封装了鸭子的三种不同的叫法:呱呱,吱吱和不会叫。

抽象出了鸭子的各种行为以后如何组合成一个完整的鸭子呐?

组合而不是继承

1. 首先我们在Duck类中加入“两个实例变量指针”,分别是“flyBehavior”和“quackBehavior”,每个具体的鸭子会动态的设置这两个实例变量指针,然后我们用两个方法“performFly”和“performQuack”来条用前面的两个实例变量指针中的具体的quack函数和fly函数。

如图:

2. 然后我们实现perfrom:

Duck::performQuack() {
    quack_behavior->quack();
}

3. 这样我们在具体的鸭子子类的构造函数中组装鸭子实现:

class MallardDuck : public Duck {
public:
    MallardDuck() {
        quackBehavior = new Quack();
        flyBehavior = new FlyWithWings();
    }
    void display() {
        cout << "I'm a real Mallard Duck" << endl;
    }
}

这样Mallard鸭子叫行为的指针就指向了一个可以quack叫的子类。

模式整体实现

Duck.h & Duck.cpp

// Duck.h created by Zillior

#ifndef DESIGN_DUCK_H
#define DESIGN_DUCK_H


#include "FlyBehavior.h"
#include "QuackBehavoir.h"

class Duck {

protected:
    QuackBehavoir* quack_behavior;

    FlyBehavior* fly_behavior;
public:
    void display();
    void performQuack();
    void performFly();

    void set_fly_behavior(FlyBehavior*);
    void set_quack_behavior(QuackBehavoir*);
};

class MallardDuck : public Duck {
public:
    MallardDuck();
    ~MallardDuck();
};

class RedheadDuck : public Duck {
public:
    RedheadDuck();
    ~RedheadDuck();
};

class RubberDuck : public Duck {
public:
    RubberDuck();
    ~RubberDuck();
};

class DecoyDuck : public Duck {
public:
    DecoyDuck();
    ~DecoyDuck();
};

#endif //DESIGN_DUCK_H
// Duck.cpp created by Zillior
#include "Duck.h"

void Duck::display() {
    performFly();
    performQuack();
}

void Duck::performQuack() {
    quack_behavior->quack();
}

void Duck::performFly() {
    fly_behavior->fly();
}

void Duck::set_fly_behavior(FlyBehavior* new_fly_behavior) {
    if (fly_behavior != nullptr)   delete fly_behavior;
    fly_behavior = new_fly_behavior;
}

void Duck::set_quack_behavior(QuackBehavoir* new_quack_behavior) {
    if (quack_behavior != nullptr)  delete  quack_behavior;
    quack_behavior = new_quack_behavior;
}

MallardDuck::MallardDuck() {
    this->quack_behavior = new Quack;
    this->fly_behavior = new FlyWithWings;
}

RedheadDuck::RedheadDuck() {
    this->quack_behavior = new Quack;
    this->fly_behavior = new FlyWithWings;
}

RubberDuck::RubberDuck() {
    this->quack_behavior = new Squeak;
    this->fly_behavior = new FlyNoWay;
}

DecoyDuck::DecoyDuck() {
    this->quack_behavior = new MuteQuack;
    this->fly_behavior = new FlyNoWay;
}

鸭子飞行行为的实现

// FlyBehavior.h Created by zillior on 18-8-20.

#ifndef DESIGN_FLYBEHAVIOR_H
#define DESIGN_FLYBEHAVIOR_H


class FlyBehavior {
private:

public:
    virtual void fly() = 0;
};

class FlyWithWings : public FlyBehavior {
private:

public:
    virtual void fly() override;
};

class FlyNoWay : public FlyBehavior {
private:

public:
    virtual void fly() override;
};


#endif //DESIGN_FLYBEHAVIOR_H
// FlyBehavior.cpp Created by zillior on 18-8-20.
//

#include <iostream>
#include "FlyBehavior.h"

void FlyWithWings::fly() {
    std::cout << "fly with wings" << std::endl;
}

void FlyNoWay::fly() {
    std::cout << "can't fly" << std::endl;
}

鸭子叫的行为的实现

// QuackBehavoir.h Created by zillior on 18-8-20.
//

#ifndef DESIGN_QUACKBEHAVOIR_H
#define DESIGN_QUACKBEHAVOIR_H


class QuackBehavoir {
private:

public:
    virtual void quack() = 0;
};

class Quack : public QuackBehavoir {
private:

public:
    void quack() override;
};

class Squeak : public QuackBehavoir {
private:

public:
    void quack() override;
};

class MuteQuack : public QuackBehavoir {
private:

public:
    void quack() override;
};


#endif //DESIGN_QUACKBEHAVOIR_H
// QuackBehavoir.cpp Created by zillior on 18-8-20.
//

#include <iostream>
#include "QuackBehavoir.h"

void Quack::quack() {
    std::cout << "quack" << std::endl;
}

void Squeak::quack() {
    std::cout << "squeak" << std::endl;
}

void MuteQuack::quack() {
    // do nothing
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值