zoukankan      html  css  js  c++  java
  • 设计模式(8)状态模式(关注状态之间的变化)

    状态模式(State Pattern)是设计模式的一种,属于行为模式。
      定义(源于Design Pattern):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
      状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。
      意图:允许一个对象在其内部状态改变时改变它的行为
      适用场景:
      1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。

      2.一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态。

    类图结构:

    这样的话让程序更加面向对象

    状态模式的好处是将与特定状态相关的行为局部化,并且将不同的状态行为分割开来。
     目的就是消除庞大的分支语句,状态模式通过把各种状态转移逻辑分布到state的子类之间,
     来减少相互间的依赖。
     什么时候使用?
     当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,就可以
     考虑状态模式。

    参考代码如下:

    #ifndef _STATE_H_
    #define _STATE_H_
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Work;
    
    class State{
    public:
    	virtual void writeProgram(Work* work) = 0;
    };
    //12 before
    class ForenoonState : public State{
    public:
    	void writeProgram(Work* work);
    };
    //12 ~ 13 middle
    class MoonState:public State{
    public:
    	void writeProgram(Work* work);
    };
    
    //12 ~ 13 middle
    class AfterMoonState:public State{
    public:
    	void writeProgram(Work* work);
    };
    
    //晚间
    class EveningState:public State{
    public:
    	void writeProgram(Work* work);
    };
    //休息
    class RestState:public State{
    public:
    	void writeProgram(Work* work);
    };
    //睡觉
    class SleepingState:public State{
    public:
    	void writeProgram(Work* work);
    };
    
    class Work{
    private:
    	State* m_current;
    	int m_hour;
    	bool m_finish;
    public:
    	Work(void):m_current(NULL),m_finish(false),m_hour(0){
    		m_current = new ForenoonState();
    	}
    	int getHour(void){
    		return m_hour;
    	}
    	void setHour(const int hour){
    		m_hour = hour;
    	}
    	bool getIsFinished(void){
    		return m_finish;
    	}
    	void setFinishFlag(const bool bFinished){
    		m_finish = bFinished;
    	}
    	void setState(State* state){
    		m_current = state;
    	}
    	void writeProgram(){
    		m_current->writeProgram(this);
    	}
    };
    
    void ForenoonState::writeProgram(Work* work){
    	if(work->getHour()<12){
    		cout<<"当前时间:"<<work->getHour()<<"点 上午工作,精神百倍"<<endl;
    	}else{
    		work->setState(new MoonState());
    		work->writeProgram();
    	}
    }
    
    void MoonState::writeProgram(Work* work){
    	if(work->getHour()<13){
    		cout<<"当前时间:"<<work->getHour()<<"点 午休,得去吃饭了!"<<endl;
    	}else{
    		work->setState(new AfterMoonState());
    		//work->writeProgram();
    	}
    }
    
    void AfterMoonState::writeProgram(Work* work){
    	if(work->getHour()<17){
    		cout<<"当前时间:"<<work->getHour()<<"点 下午状态还可以,继续努力!"<<endl;
    	}else{
    		work->setState(new EveningState());
    		work->writeProgram();
    	}
    }
    
    void EveningState::writeProgram(Work* work){
    	if(work->getIsFinished()){
    		work->setState(new RestState());
    		work->writeProgram();
    	}else{
    		if(work->getHour()<21){
    			cout<<"当前时间:"<<work->getHour()<<"点 加班啊,疲惫之极!"<<endl;
    		}else{
    			work->setState(new SleepingState());
    			work->writeProgram();
    		}
    	}
    }
    
    void RestState::writeProgram(Work* work){
    	cout<<"当前时间:"<<work->getHour()<<"点 下班回家了!"<<endl;
    }
    
    void SleepingState::writeProgram(Work* work){
    	cout<<"当前时间:"<<work->getHour()<<"点 不行了睡着了!"<<endl;
    }
    
    #endif
    
    void main(){
    	Work* work = new Work();
    	work->setHour(9);
    	work->writeProgram();
    	work->setHour(10);
    	work->writeProgram();
    	work->setHour(12);
    	work->writeProgram();
    	work->setHour(13);
    	work->writeProgram();
    	work->setHour(14);
    	work->writeProgram();
    	work->setHour(17);
    	work->writeProgram();
    	
    	work->setFinishFlag(false);
    	work->writeProgram();
    	
    	work->setHour(19);
    	work->writeProgram();
    	work->setHour(21);
    	work->writeProgram();
    }
    

    对于状态频繁变更需要考虑状态模式。

    作者:张锋
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
    更多精彩文章可以观注
    微信公众号 soft张三丰

    微信交流群,添加群主微信,邀请入群
  • 相关阅读:
    Linux 用户 quote 配置 说明
    Linux 用户和用户组 配置说明
    ORA-00600: [kck_rls_check must use (11,0,0,0,0) or lower] 故障解决
    Oracle Data Guard PING[ARC2]: Heartbeat failed to connect to standby ''. Error is 12514 故障分析
    Oracle 11g RAC OCR 与 db_unique_name 配置关系 说明
    Data Guard 奇葩的 ORA-16191: Primary log shipping client not logged on standby 问题
    Oracle 11gR2 RMAN Duplicate 触发PLS-00201: identifier 'DBMS_RCVCAT.GETDBID' must be declared 错误
    RMAN RAC 到 单实例 duplicate 自动分配通道 触发 ORA-19505 错误
    Secure CRT 自动记录日志 配置 小记
    VBox fdisk 不显示 添加的硬盘 解决方法
  • 原文地址:https://www.cnblogs.com/skyme/p/2022062.html
Copyright © 2011-2022 走看看