设计模式01 - 策略模式

@brief
学习《Head First设计模式》中第一节 - “策略模式”
(由于原书全是 java,自己还不是很适应)
策略模式的定义:
策略模式顶一个一个算法族,分别封装起来,使得它们之间可以互相交换。
策略让算法的变化独立于使用它的客户。

设计原则:
针对接口编程,而不是针对实现编程。

问题引入:
当设计完 Duck类后,有的派生类duck 需要 fly() 方法。
=> 一种做法是:直接在 class Duck() 中添加 fly()方法。
=> 但是不是所有的 duck 都能够飞,所以这种做法是错误的(所有的派生类都可以调用了)
“总结”: 不能通过 继承 来达到 复用 的目的,当涉及到 维护 时会很麻烦。
解决办法:
实行功能分离:
=> 把变化的部分取出并封装,这样,以后就可以修改或扩展这个部分,而不会影响其它不需要变化的部分。
=> 这样系统会更有弹性。

main.cpp

/**
 * @file main.cpp
 * @author GaoJune (gaojune_better@q.com)
 * @version 0.1
 * @date 2022-04-28
 * @copyright Copyright (c) 2022
 * 
 * 文件介绍:
 *  Duck.h 为最基本的class,里面封装了2个接口,以及所有 duck 的公共函数
 *  该 “ has-A ” 中,每只鸭子有一个FlayBehavior和QuackBehavior,以委托飞行和叫。
 *  FlayBehavior.h 和 QuackBehavior.h 分别对 fly()、quack() 进行封装
 */

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

// 前置声明
class Duck;
class FlyBehavior;
class QuackBehavior;


// 设计鸭子类 MiniDuckSimulator,并为其添加属性
class MiniDuckSimulator : public Duck{
public:
    MiniDuckSimulator() {
        std::cout << "ctor MiniDuckSimulator" << std::endl;

        // 给该类添加一些新特性
        _fly_behavior = new FlyWithWings();
        _quack_behavior = new Squeak();
    }
    ~MiniDuckSimulator() {
        std::cout << "dtor MiniDuckSimulator" << std::endl;
    }
};

int main( ){
    // 开始测试 
    Duck* mallard = new MiniDuckSimulator();
   
    mallard->Swim();
    mallard->Display();
    mallard->PerformFly();
    mallard->PerformQuack();

    // 改变鸭子的飞行、叫声
    std::cout << "改变鸭子飞行、叫声 技能" << std::endl;
    mallard->SetFlyBehavior( new FlyNoWay() );
    mallard->SetQuackBehavior( new MuteQuack() );
    mallard->PerformFly();
    mallard->PerformQuack();

    return 0;
}

Duck.h

/**
 * @brief:
 * Duck类中包含两个抽象类: FlyBehavior、 QuackBehavior
 *      FlyBehavior   接口:对 fly 做了封装
 *      QuackBehavior 接口:对 Quack(嘎嘎)做了封装
 */

#pragma once
#include <iostream>
#include "FlyBehavior.h"
#include "QuackBehavior.h"

class Duck{
public:
    Duck(){
        std::cout << "ctor Duck" << std::endl;
    }
    ~Duck(){
        std::cout << "dtor Duck" << std::endl;
        delete _fly_behavior;
        delete _quack_behavior;
    }

public:
    // 所有鸭子的公共行为
    void Swim( ){
        std::cout << "Ducks can swim!" << std::endl;
    }
    
    void Display( ){
        std::cout << "Duck's Display" << std::endl;
    }

    // 委托给接口执行
    void PerformFly( ){
        _fly_behavior->Fly();
    }
    void PerformQuack( ){
        _quack_behavior->quack();
    }

    // 改变 duck 的技能
    // eg. 传入 new FlyNoWay()
    void SetFlyBehavior( FlyBehavior *fb ){
        _fly_behavior = fb;
    }
    void SetQuackBehavior( QuackBehavior *qb ){
        _quack_behavior = qb;
    }


// 这里不能设置 private,不然无法修改指针指向
protected:
    FlyBehavior*     _fly_behavior;
    QuackBehavior*   _quack_behavior; 
};

FlyBehavior.h

/**
 * @brief:
 * FlyBehavior :飞行行为基类
 *      class FlyWithWings、class FlyNoWay会继承该接口
 */

#pragma once
#include <iostream>

class FlyBehavior{
public:
    FlyBehavior(){
        std::cout << "ctor FlyBehavior" << std::endl;
    }
    ~FlyBehavior(){
        std::cout << "dtor FlyBehavior" << std::endl;
    }

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

/**
 * @brief: 
 * FlyWithWings :对 能飞 的鸭子进行飞行实现
 */
class FlyWithWings : public FlyBehavior{
public:
    FlyWithWings(){
        std::cout << "ctor FlyWithWings" << std::endl;
    }
    ~FlyWithWings(){
        std::cout << "dtor FlyWithWings" << std::endl;
    }

public:
    void Fly( ){
        std::cout << "I'm flying!" << std::endl;
    }
};

/**
 * @brief:
 * FlyNoWay :对不能飞的鸭子进行飞行实现
 */
class FlyNoWay : public FlyBehavior{
    void Fly( ){
        std::cout << "I can't fly" << std::endl;
    }
};

QuackBehavior.h

/**
 * @brief
 * QuackBehavior :所有动作行为基类
 *      class Quack、class MuteQuack、Squeak 会继承该接口
 */

#pragma once
#include <iostream>

class QuackBehavior{
public:
    QuackBehavior() = default;
    ~QuackBehavior() = default;

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


// 嘎嘎叫
class Quack : public QuackBehavior{
public:
    Quack(){
        std::cout << "ctor Quack" << std::endl;
    }
    ~Quack(){
        std::cout << "dtor Quack" << std::endl;
    }

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

// 不会叫
class MuteQuack : public QuackBehavior{
public:
    MuteQuack(){
        std::cout << "ctor MuteQuack" << std::endl;
    }
    ~MuteQuack(){
        std::cout << "dtor MuteQuack" << std::endl;
    }

public:
    void quack( ){
        std::cout << " <<Slience>> " << std::endl;
    }
};

// 吱吱叫
class Squeak : public QuackBehavior{
public:
    Squeak(){
        std::cout << "ctor Squeak" << std::endl;
    }
    ~Squeak(){
        std::cout << "dtor Squeak" << std::endl;
    }

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值