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

策略模式

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

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

  1. //behavior.h
  2. #ifndef BEHAVIOR_H
  3. #define BEHAVIOR_H
  4. class FlyBehavior
  5. {
  6. public:
  7. FlyBehavior() {}
  8. virtual void fly() = 0;
  9. };
  10. class QuackBehavior
  11. {
  12. public:
  13. QuackBehavior() {}
  14. virtual void quack() = 0;
  15. };
  16. class FlyWithWings: public FlyBehavior
  17. {
  18. public:
  19. void fly() override;
  20. };
  21. class FlyNoWay: public FlyBehavior
  22. {
  23. public:
  24. void fly() override;
  25. };
  26. class FlyRocketPowered: public FlyBehavior
  27. {
  28. public:
  29. void fly() override;
  30. };
  31. class Quack: public QuackBehavior
  32. {
  33. public:
  34. void quack() override;
  35. };
  36. class Squeak: public QuackBehavior
  37. {
  38. public:
  39. void quack() override;
  40. };
  41. class MuteQuack: public QuackBehavior
  42. {
  43. public:
  44. void quack() override;
  45. };
  46. #endif // BEHAVIOR_H
  1. //behavior.cpp
  2. #include "behavior.h"
  3. #include <iostream>
  4. using std::cout;
  5. using std::endl;
  6. void FlyWithWings::fly()
  7. {
  8. cout << "I am flying!" << endl;
  9. }
  10. void FlyNoWay::fly()
  11. {
  12. cout << "I cannot fly!" << endl;
  13. }
  14. void FlyRocketPowered::fly()
  15. {
  16. cout << "I am fly with a rocket!" << endl;
  17. }
  18. void Quack::quack()
  19. {
  20. cout << "Quack" << endl;
  21. }
  22. void Squeak::quack()
  23. {
  24. cout << "Squeak" << endl;
  25. }
  26. void MuteQuack::quack()
  27. {
  28. cout << "<< Silence >>" << endl;
  29. }

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

  1. //duck.h
  2. #ifndef DUCK_H
  3. #define DUCK_H
  4. #include "behavior.h"
  5. class Duck
  6. {
  7. public:
  8. Duck();
  9. void performQuack();
  10. void performFly();
  11. virtual void display() = 0;
  12. void setFlyBehavior(FlyBehavior * fb);
  13. protected:
  14. FlyBehavior *m_flyBehavior;
  15. QuackBehavior *m_quackBehavior;
  16. };
  17. #endif // DUCK_H
  1. //duck.cpp
  2. #include "duck.h"
  3. Duck::Duck()
  4. {
  5. }
  6. void Duck::performQuack()
  7. {
  8. m_quackBehavior->quack();
  9. }
  10. void Duck::performFly()
  11. {
  12. m_flyBehavior->fly();
  13. }
  14. void Duck::setFlyBehavior(FlyBehavior * fb)
  15. {
  16. if(m_flyBehavior != nullptr)
  17. {
  18. delete m_flyBehavior;
  19. }
  20. m_flyBehavior = fb;
  21. }

例子中有两种 Duck:

  1. mallardduck.h
  2. #ifndef MALLARDDUCK_H
  3. #define MALLARDDUCK_H
  4. #include "duck.h"
  5. class MallardDuck : public Duck
  6. {
  7. public:
  8. MallardDuck();
  9. void display() override;
  10. };
  11. #endif // MALLARDDUCK_H
  1. //mallardduck.cpp
  2. #include "mallardduck.h"
  3. #include <iostream>
  4. using std::cout;
  5. using std::endl;
  6. MallardDuck::MallardDuck()
  7. {
  8. m_quackBehavior = new Quack;
  9. m_flyBehavior = new FlyWithWings;
  10. }
  11. void MallardDuck::display()
  12. {
  13. cout << "I am a real Mallard Duck" << endl;
  14. }
  1. //modelduck.h
  2. #ifndef MODELDUCK_H
  3. #define MODELDUCK_H
  4. #include "duck.h"
  5. class ModelDuck : public Duck
  6. {
  7. public:
  8. ModelDuck();
  9. void display() override;
  10. };
  11. #endif // MODELDUCK_H
  1. //modelduck.cpp
  2. #include "modelduck.h"
  3. #include <iostream>
  4. using std::cout;
  5. using std::endl;
  6. ModelDuck::ModelDuck()
  7. {
  8. m_flyBehavior = new FlyNoWay;
  9. m_quackBehavior = new Quack;
  10. }
  11. void ModelDuck::display()
  12. {
  13. cout << "I am a model duck" << endl;
  14. }

最后是 main 函数。

  1. #include "mallardduck.h"
  2. #include "modelduck.h"
  3. int main(int argc, char *argv[])
  4. {
  5. Duck * mallard = new MallardDuck;
  6. mallard->display();
  7. mallard->performQuack();
  8. mallard->performFly();
  9. Duck * model = new ModelDuck;
  10. model->display();
  11. model->performFly();
  12. model->setFlyBehavior(new FlyRocketPowered);
  13. model->performFly();
  14. }

《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. springboot 学习之路 22 (读取自定义文件)

    springboot读取自定义的properties文件: package com.huhy.demo.properties; import lombok.Data; import org.sprin ...

  2. 【Python】keras使用LSTM拟合曲线

    keras生成的网络结构如下图: 代码如下: from sklearn.preprocessing import MinMaxScaler from keras.models import Seque ...

  3. Ubuntu16下配置支持Windows访问的samba共享

    一.安装Ubuntu samba服务器 $ sudo apt-get install samba $ sudo apt-get install smbclient # Linux客户端测试用 二.创建 ...

  4. 外网访问局域网ip的方法

    https://jingyan.baidu.com/article/48b558e335e3ac7f39c09a59.html 步骤: 1.浏览器内输入:192.168.1.1进入路由器管理界面 2. ...

  5. C语言开发的思考

    维护过十万行代码的通信协议,自己从头开始开发过几万行的代码,步骤: 1.移植性.为移植性对数据类型做重新定义. 2.内存计数.不要直接使用malloc和free,而是给所有类型的内存申请定义类型,并计 ...

  6. python曲线拟合

    http://blog.sina.com.cn/s/blog_aed5bd1d0102vid7.html 1.多项式拟合范例: import matplotlib.pyplot as plt impo ...

  7. Linux命令大全总结

    目录方面的命令:ls,dir,cd,clear,mkdir ls 显示指定目录的文件和目录 ls -a 列出目录下的所有文件,包括以 . 开头的隐藏文件 ls -l 显示指定目录的详细列表 ls -R ...

  8. 20145203盖泽双 《网络对抗技术》实践八:Web基础

    20145203盖泽双 <网络对抗技术>实践八:Web基础 1.实践目标 (1)编写Web前端--含有表单的HTML代码. (2)编写Web前端--javascipt验证用户名.密码的代码 ...

  9. docker官方文档学习-1-Docker for mac安装配置

    https://docs.docker.com/docker-for-mac/ Get started with Docker for Mac 首先像在本博客docker-1-环境安装及例子实践处将环 ...

  10. go标准库的学习-crypto/aes

    参考:https://studygolang.com/pkgdoc 导入方式: import "crypto/aes" aes包实现了AES加密算法,参见U.S. Federal ...