最近在学习设计模式,用的是 《Head First 设计模式》这本书。感觉这本书写的还是很不错的,深入浅出的介绍了各种常用的设计模式。唯一有点不方便的地方是这本书的例子全都是用的 Java 来实现的。而我主要是用 C++。所以就动手将书上的代码用 C++ 来实现了一遍。

策略模式

这一章用的是个 Duck 的例子。C++ 没有 interface 的概念,都是用类来实现的。

我将各个策略都放到了 behavior.h 和 behavior.cpp 中。

//behavior.h
#ifndef BEHAVIOR_H
#define BEHAVIOR_H

class FlyBehavior
{
public:
    FlyBehavior() {}
    virtual void fly() = 0;
};

class QuackBehavior
{
public:
    QuackBehavior() {}
    virtual void quack() = 0;
};

class FlyWithWings: public FlyBehavior
{
public:
    void fly() override;
};

class FlyNoWay: public FlyBehavior
{
public:
    void fly() override;
};

class FlyRocketPowered: public FlyBehavior
{
public:
    void fly() override;
};

class Quack: public QuackBehavior
{
public:
    void quack() override;
};

class Squeak: public QuackBehavior
{
public:
    void quack() override;
};

class MuteQuack: public QuackBehavior
{
public:
    void quack() override;
};
#endif // BEHAVIOR_H
//behavior.cpp
#include "behavior.h"
#include <iostream>

using std::cout;
using std::endl;

void FlyWithWings::fly()
{
    cout << "I am flying!" << endl;
}

void FlyNoWay::fly()
{
    cout << "I cannot fly!" << endl;
}

void FlyRocketPowered::fly()
{
    cout << "I am fly with a rocket!" << endl;
}

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

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

void MuteQuack::quack()
{
    cout << "<< Silence >>" << endl;
}

Duck 包含了两种 Behavior。Duck 本身设计为一个纯虚类,真实的各种鸭子都要从这里继承。

//duck.h
#ifndef DUCK_H
#define DUCK_H

#include "behavior.h"

class Duck
{
public:
    Duck();
    void performQuack();
    void performFly();
    virtual void display() = 0;

    void setFlyBehavior(FlyBehavior * fb);
protected:
    FlyBehavior *m_flyBehavior;
    QuackBehavior *m_quackBehavior;

};

#endif // DUCK_H
//duck.cpp
#include "duck.h"
Duck::Duck()
{

}

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

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

void Duck::setFlyBehavior(FlyBehavior * fb)
{
    if(m_flyBehavior != nullptr)
    {
        delete m_flyBehavior;
    }
    m_flyBehavior = fb;
}

例子中有两种 Duck:

mallardduck.h
#ifndef MALLARDDUCK_H
#define MALLARDDUCK_H

#include "duck.h"

class MallardDuck : public Duck
{
public:
    MallardDuck();
    void display() override;
};

#endif // MALLARDDUCK_H
//mallardduck.cpp
#include "mallardduck.h"
#include <iostream>

using std::cout;
using std::endl;

MallardDuck::MallardDuck()
{
    m_quackBehavior = new Quack;
    m_flyBehavior = new FlyWithWings;
}

void MallardDuck::display()
{
    cout << "I am a real Mallard Duck" << endl;
}
//modelduck.h
#ifndef MODELDUCK_H
#define MODELDUCK_H

#include "duck.h"

class ModelDuck : public Duck
{
public:
    ModelDuck();
    void display() override;
};
#endif // MODELDUCK_H
//modelduck.cpp
#include "modelduck.h"
#include <iostream>

using std::cout;
using std::endl;

ModelDuck::ModelDuck()
{
    m_flyBehavior = new FlyNoWay;
    m_quackBehavior = new Quack;
}

void ModelDuck::display()
{
    cout << "I am a model duck" << endl;
}

最后是 main 函数。

#include "mallardduck.h"
#include "modelduck.h"

int main(int argc, char *argv[])
{
    Duck * mallard = new MallardDuck;
    mallard->display();
    mallard->performQuack();
    mallard->performFly();

    Duck * model = new ModelDuck;
    model->display();
    model->performFly();
    model->setFlyBehavior(new FlyRocketPowered);
    model->performFly();
}

《Head First 设计模式》例子的C++实现(1 策略模式)的更多相关文章

  1. Java 设计模式系列(十二)策略模式(Strategy)

    Java 设计模式系列(十二)策略模式(Strategy) 策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以 ...

  2. 设计模式(一):“穿越火线”中的“策略模式”(Strategy Pattern)

    在前段时间呢陆陆续续的更新了一系列关于重构的文章.在重构我们既有的代码时,往往会用到设计模式.在之前重构系列的博客中,我们在重构时用到了“工厂模式”.“策略模式”.“状态模式”等.当然在重构时,有的地 ...

  3. 学C#之设计模式系列笔记(1)策略模式

    一.借鉴说明 1.<Head First Design Patterns>(中文名<深入浅出设计模式>) 2.维基百科,策略模式,https://zh.wikipedia.or ...

  4. Java设计模式从精通到入门三 策略模式

    介绍 我尽量用最少的语言解释总结: Java23种设计模式之一,属于行为型模式.一个类的行为或者算法可以在运行时更改,策略对象改变context对象执行算法. 应用实例: ​ 以周瑜赔了夫人又折兵的例 ...

  5. JAVA设计模式详解(一)----------策略模式

    策略模式,顾名思义就是设计一个策略算法,然后与对象拆分开来将其单独封装到一系列策略类中,并且它们之间可以相互替换.首先LZ举一个例子为大家引出这一个模式. 例子:某公司的中秋节奖励制度为每个员工发放2 ...

  6. 设计模式学习总结(八)策略模式(Strategy)

    策略模式,主要是针对不同的情况采用不同的处理方式.如商场的打折季,不同种类的商品的打折幅度不一,所以针对不同的商品我们就要采用不同的计算方式即策略来进行处理. 一.示例展示: 以下例子主要通过对手机和 ...

  7. 《大话设计模式》ruby版代码:策略模式

    需求: 商场收银软件,根据客户购买物品的单价和数量,计算费用,会有促销活动,打八折,满三百减一百之类的. 一,使用工厂模式. # -*- encoding: utf-8 -*- #现金收费抽象类 cl ...

  8. Android设计模式(二)--策略模式

    1.定义: The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them inter ...

  9. LVOOP设计模式在路上(二)-- 策略模式

    前言 最近工作还挺忙的,连着好些周都是单休了,今天休息在家就来写写关于策略模式的理解和labivew的实现. 正文 1.什么是策略模式 定义是这样描述的:它定义了算法家族,分别封装起来,让它们之间可以 ...

  10. Java设计模式之(十四)——策略模式

    1.什么是策略模式? Define a family of algorithms, encapsulate each one, and make them interchangeable. Strat ...

随机推荐

  1. Android Studio 通过一个登录功能介绍SQLite数据库的使用

    前言: SQLite简介:是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中.它是D.RichardHipp建立的公有领域项目.它的设计目标是嵌入式的,而且目前已经在 ...

  2. BeanFactory和ApplicationContext的比较

    1.BeanFactory实例化后,不会马上实例化Bean:ApplicationContext在实例化后紧跟着就会实例化Bean 2.ApplicationContext还实现了ResourceLo ...

  3. 对JS作用域和作用域链的理解

    理解好javascript的变量作用域和链式调用机制对用好变量起着关键的作用,下面我来谈谈这两个概念的理解. (1)链式调用机制 作用域链的定义:函数在调用参数时会从函数内部到函数外部逐个”搜索“参数 ...

  4. (网页)Uncaught ReferenceError: pageImport is not defined

    在js开发中,很多人遇到类似问题,都找不到解决方法.Uncaught ReferenceError: $ is not defined,在这里给大家提供几个解决方法. 1.出现这个错误,最可能的是引用 ...

  5. go 排序sort的使用

    已知一个的struct组成的数组,现在要按照数组中的一个字段排序.python有sort方法,那golang要怎么实现呢?其实golang也有sort方法,并且使用简单,功能强大. 我们先看一下sor ...

  6. MSSQL一种取代游标的方案

    今天看到一篇文章写的自己整理记录下,据说比用游标快. DECLARE @字段1 数据类型; DECLARE @字段2 数据类型; DECLARE @TMP_WHILE_ID INT; ,),TMP_W ...

  7. Python实例---模拟微信网页登录(day5)

    第六步: 实现发送/接受消息---day5代码 settings.py """ Django settings for weixin project. Generated ...

  8. 使用python3.6和django1.9的xadmin 遇到坑,__unicode__()和__str__()

    原因:python版本为3.6,Python3.X的版本不可使用__unicode__()(python2.x可用),应改为__str__().

  9. 中介模型,cbv视图,和查询优化

    中介模型: 处理类似搭配 pizza 和 topping 这样简单的多对多关系时,使用标准的ManyToManyField  就可以了.但是,有时你可能需要关联数据到两个模型之间的关系上. 例如,有这 ...

  10. nodejs中async使用

    waterfall , parallel ,  series  ,  eachSeries //var async = require('async'); /*** *① * 串行有关联 执行每个函数 ...