设计模式C++实现 ——状态模式

软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性:封装、继承、多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累。最近看设计模式的书,对于每个模式,用C++写了个小例子,加深一下理解。主要参考《大话设计模式》和《设计模式:可复用面向对象软件的基础》两本书。本文介绍状态模式的实现。

       状态模式:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。它有两种使用情况:(1)一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。(2)一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。本文的例子为第一种情况,以战争为例,假设一场战争需经历四个阶段:前期、中期、后期、结束。当战争处于不同的阶段,战争的行为是不一样的,也就说战争的行为取决于所处的阶段,而且随着时间的推进是动态变化的。下面给出相应的UML图。


       实现的代码比较简单,给出War类和State类,War类中含State对象(指针形式)。

[cpp] view plaincopyprint?
  1. class War;  
  2. class State   
  3. {  
  4. public:  
  5.     virtual void Prophase() {}  
  6.     virtual void Metaphase() {}  
  7.     virtual void Anaphase() {}  
  8.     virtual void End() {}  
  9.     virtual void CurrentState(War *war) {}  
  10. };  
  11. //战争  
  12. class War  
  13. {  
  14. private:  
  15.     State *m_state;  //目前状态  
  16.     int m_days;      //战争持续时间  
  17. public:  
  18.     War(State *state): m_state(state), m_days(0) {}  
  19.     ~War() { delete m_state; }  
  20.     int GetDays() { return m_days; }  
  21.     void SetDays(int days) { m_days = days; }  
  22.     void SetState(State *state) { delete m_state; m_state = state; }  
  23.     void GetState() { m_state->CurrentState(this); }  
  24. };  

           给出具体的状态类:

[cpp] view plaincopyprint?
  1. //战争结束  
  2. class EndState: public State  
  3. {  
  4. public:  
  5.     void End(War *war) //结束阶段的具体行为  
  6.     {  
  7.         cout<<"战争结束"<<endl;  
  8.     }  
  9.     void CurrentState(War *war) { End(war); }  
  10. };  
  11. //后期  
  12. class AnaphaseState: public State  
  13. {  
  14. public:  
  15.     void Anaphase(War *war) //后期的具体行为  
  16.     {  
  17.         if(war->GetDays() < 30)  
  18.             cout<<"第"<<war->GetDays()<<"天:战争后期,双方拼死一搏"<<endl;  
  19.         else  
  20.         {  
  21.             war->SetState(new EndState());  
  22.             war->GetState();  
  23.         }  
  24.     }  
  25.     void CurrentState(War *war) { Anaphase(war); }  
  26. };  
  27. //中期  
  28. class MetaphaseState: public State  
  29. {  
  30. public:  
  31.     void Metaphase(War *war) //中期的具体行为  
  32.     {  
  33.         if(war->GetDays() < 20)  
  34.             cout<<"第"<<war->GetDays()<<"天:战争中期,进入相持阶段,双发各有损耗"<<endl;  
  35.         else  
  36.         {  
  37.             war->SetState(new AnaphaseState());  
  38.             war->GetState();  
  39.         }  
  40.     }  
  41.     void CurrentState(War *war) { Metaphase(war); }  
  42. };  
  43. //前期  
  44. class ProphaseState: public State  
  45. {  
  46. public:  
  47.     void Prophase(War *war)  //前期的具体行为  
  48.     {  
  49.         if(war->GetDays() < 10)  
  50.             cout<<"第"<<war->GetDays()<<"天:战争初期,双方你来我往,互相试探对方"<<endl;  
  51.         else  
  52.         {  
  53.             war->SetState(new MetaphaseState());  
  54.             war->GetState();  
  55.         }  
  56.     }  
  57.     void CurrentState(War *war) { Prophase(war); }  
  58. };  
         使用方式:

[cpp] view plaincopyprint?
  1. //测试案例  
  2. int main()  
  3. {  
  4.     War *war = new War(new ProphaseState());  
  5.     for(int i = 1; i < 40;i += 5)  
  6.     {  
  7.         war->SetDays(i);  
  8.         war->GetState();  
  9.     }  
  10.     delete war;  
  11.     return 0;  
  12. }  
     本人享有博客文章的版权,转载请标明出处 http://blog.csdn.net/wuzhekai1985

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/435866.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Apache在windows的设置

本节主要考虑windows的安装和配置使用&#xff0c;Linux 参考&#xff1a;http://httpd.apache.org/docs/2.2/stopping.html 一 Apache在windows的安装主要支持windows NT 86系统&#xff0c;安装文件或源代码下载页&#xff1a;http://httpd.apache.org/download.cgi。安装过程…

【转】正确认识动脉压力波形

转自&#xff1a;https://www.sohu.com/a/288192545_377325 前言 早在50多年前&#xff0c;就已经在麻醉患者中开始进行直接动脉血压监测。尽管对动脉压力波形的形态和细节进行分析可以给我们提供一些有用的诊断信息&#xff0c;但现代的医生似乎很少关注它。临床实践中的这些…

2008服务器ftp上传文件,win2008怎么开通服务器ftp上传

win2008怎么开通服务器ftp上传 内容精选换一换GPU加速型实例如需使用OpenGL/DirectX/Vulcan等图形加速能力则需要安装GRID驱动并自行购买和配置使用GRID License。此外&#xff0c;GRID驱动配合vDWS类型License&#xff0c;也支持CUDA&#xff0c;用来满足既需要计算加速也需要…

【转】温故之.NET 异步

转自&#xff1a;https://zhuanlan.zhihu.com/p/38537169 这篇文章包含以下内容 异步基础基于任务的异步模式部分 API 介绍 异步基础 所谓异步&#xff0c;对于计算密集型的任务&#xff0c;就是以线程为基础的多任务。而在具体使用中&#xff0c;使用线程池里面的线程还是新…

C库函数—strcpy实现

strcpy&#xff1a;将原串拷贝到目的串&#xff0c;不拷贝NULL 以下为具体实现&#xff1a; #include<stdio.h> #include<stdlib.h> #include<string.h> char * strcpy(char * strDest, const char * strSrc){ if(NULL strSrc || NULL strDest){ …

从数据库读写RadioButtonList选中的值

从数据库取出RadioButtonList选中的值 string str "体育";//这一项可以从数据库中读出 for (int j 0; j < this.RadioButtonList1.Items.Count; j) { if (str this.RadioButtonList1.Items[j].Text.ToString()) { this.RadioButtonList1.Items[j].Selected…

【转】DICOM中几个判断图像方向的tag

转自&#xff1a;https://www.cnblogs.com/h2zZhou/p/9072967.html 在DICOM标准里&#xff0c;有三个TAG与成像的方向相关。 参考来源&#xff1a;Kitware关于DICOM方向的说明 http://public.kitware.com/IGSTKWIKI/index.php/DICOM_data_orientation 包括 1、Image Positi…

贪心算法的几个应用

贪心算法具有2个性质&#xff1a; 1、贪心选择性质&#xff1a;只在当前状态下做最优选择&#xff0c;即局部最优选择&#xff0c;再自顶向下&#xff0c;去解做出这个选择后产生的相应子问题。每做一次选择&#xff0c;问题就转化为规模更小的子问题。对于一个具体问题&#x…

C#类和接口、虚方法和抽象方法及值类型和引用类型的区别

1.C#类和接口的区别 接口是负责功能的定义&#xff0c;项目中通过接口来规范类&#xff0c;操作类以及抽象类的概念&#xff01; 而类是负责功能的具体实现&#xff01; 在类中也有抽象类的定义&#xff0c;抽象类与接口的区别在于&#xff1a; 抽象类是一个不完全的类&#xf…

【转】DICOM医学图像读取涉及到的医学坐标体系

转&#xff1a;https://blog.csdn.net/sunyao_123/article/details/78975816 确定患者的位置和躺的方向主要有3个标签: (0018, 5100) Patient Position CS: ‘HFS’ (0020, 0032) Image Position (Patient) DS: [‘-167’, ‘-92’, ‘-28.5’] (0020, 0037) Image Orientatio…

学习 SQL 语句 - Select(4): 排序

Order By Asc|Desc本例效果图:代码文件:unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls, ExtCtrls, Grids, DBGrids, DB, ADODB;typeTForm1 class(TForm)DBGrid1: TDBGrid;DataSource1: TDataSource;…

二叉树总结一

二叉树的知识点1&#xff1a; 二叉树存储结构 前序建立二叉树 前序遍历、中序遍历、后序遍历&#xff08;递归、非递归&#xff09; 二叉树节点总数 二叉树叶子节点数 二叉树深度 遍历二叉树第i层节点 分层遍历二叉树&#xff08;递归、非递归&#xff09; 求二叉树中节点的最大…

【转】Ubuntu 16.04 远程桌面

转自&#xff1a;实现Windows直接远程访问Ubuntu 18.04&#xff08;旧版本也支持,无需安装第三方桌面,直接使用自带远程工具&#xff09; - 法号阿兴 - 博客园 一、设置Ubuntu 16.04 允许进行远程控制 首先&#xff0c;我们先设置Ubuntu的远程控制&#xff0c;将其设置为允许被…

GridView应用整理

2009年5月31日下午 21:58:38 获取GridView中RowCommand的当前选中行索引 <asp:GridView ID"BookGridView" runat"server"><Columns><asp:BoundField DataField"id" HeaderText"图书编号" /><asp:BoundField Data…

【转】VNC不同软件之间的联系与区别

转自&#xff1a;http://www.52iot.net/book/net/76.mhtml 如果不是经常远程不建议使用VNC&#xff0c;毕竟比较耗资源 不建议使用vnc&#xff0c; 如果只是使用文件服务&#xff0c;可以通过ssh协议的客户端访问过去操作。 现在gnome&#xff0c;kde, unity都是内置的&#x…

二叉树总结二

二叉树基本知识点2&#xff1a; 二叉树的非递归后序遍历 前序遍历是&#xff1a;根、左、右&#xff0c;后序遍历是&#xff1a;左、右、根&#xff0c;观察发现&#xff1a;前序和后序刚好遍历顺序相反。由于非递归后序遍历需要保存根节点及第几次访问&#xff0c;比较麻烦。可…

【转】Ubuntu下使用sysv-rc-conf管理服务

转自&#xff1a;https://www.linuxidc.com/Linux/2016-11/136834.htm sysv-rc-conf简介 sysv-rc-conf是一个强大的服务管理程序&#xff0c;群众的意见是sysv-rc-conf比chkconfig、rcconf好用。 背景知识 Ubuntu运行级别 Linux 系统任何时候都运行在一个指定的运行级上&…

几个常用SQL2000语句

排名语句select *,(select count(1) 1 from tPlanApply where applyquantity> a.applyquantity ) as 名次 from tPlanApply a order by 名次 替换语句 SQL code update tbset 字段replace(字段,替换后字符串,替换前字符串) 转载于:https://www.cnblogs.com/delphix/archiv…

WINCE6.0支持Multiple XIP

1. Multiple XIP support XIP(eXecute-In-Place)是本地执行&#xff0c;允许在ROM芯片内执行XIP区域(region)的应用代码&#xff0c;而不必再把代码读取到RAM中来执行。WINCE支持我们在单个系统中构建(construct)多个XIP区域&#xff0c;基于下面的理由使用多个XIP区域来代替…

【转】How to install VNC server on ubuntu 14.04

转自&#xff1a;https://www.krizna.com/ubuntu/install-vnc-server-ubuntu-14-04/ VNC server is used to share graphical desktop which can be controlled from other computers . This guide is helpful to install VNC server on Ubuntu Desktop 14.04, Ubuntu server …