最近在学习设计模式,用的是 《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. Java并发编程(八)同步容器

    为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器.并发容器.阻塞队列.Synchronizer(比如CountDownLatch) 一.为什么会出现同步容器? ...

  2. Android Java中的一些使用例子

    connectivity= ConnectivityService.getInstance(context); ServiceManager.addService(Context.CONNECTIVI ...

  3. centos7 Linux 安装jdk1.8

    在CentOS7上安装JDK1.8 1 通过 xshell 连接到CentOS7 服务器: 2 进入到目录 /usr/local/ 中(一般装应用环境我们都会在这个目录下装,也可自行选择目录): cd ...

  4. 我的简历 PHP Java C# 技术总监

          石先生 ID:303321266 目前正在找工作 13611326258 hr_msn@163.com 男|32 岁 (1985/08/06)|现居住北京-海淀区|12年工作经验     ...

  5. [20180319]直接路径读特例12c.txt

    [20180319]直接路径读特例12c.txt --//昨天的测试突然想起以前遇到的直接路径读特例,在12c重复测试看看. 1.环境:SCOTT@test01p> @ ver1 PORT_ST ...

  6. WCF服务端开发和客户端引用小结

    1.服务端开发 1.1 WCF服务创建方式 创建一个WCF服务,总是会创建一个服务接口和一个服务接口实现.通常根据服务宿主的不同,有两种创建方式. (1)创建WCF应用程序 通过创建WCF服务应用程序 ...

  7. 常用Linux 服务器命令--各种性能指标命令

    如果你想知道你的服务器正在做干什么,你就需要了解一些基本的命令,一旦你精通了这些命令,那你就是一个专业的 Linux 系统管理员. 监控命令## iostat### iostat命令用来显示存储系统的 ...

  8. Mac下配置apache

    一.前言 今天遇到问题,怎么配置apache在Mac上,原来Mac自带apache,只需要自己开启配置一下就行了. 二.步骤: 1.修改apache的http_conf文件 打开finder前往/pr ...

  9. python框架面试题联系

    1.对 MVC,MVT 解读的理解? M:Model,模型,和数据库进行交互 V:View,视图,负责产生 Html 页面 C:Controller,控制器,接收请求,进行处理,与 M 和 V 进行交 ...

  10. Shiro-Subject 分析

    Subject反正就好像呈现的视图.所有Subject 都绑定到SecurityManager,与Subject的所有交互都会委托给SecurityManager:可以把Subject认为是一个门面: ...