状态模式是根据其状态变化来改变对象的行为,允许对象根据内部状态来实现不同的行为。内容类可以具有大量的内部状态,每当调用实现时,就委托给状态类进行处理。

作用

当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。

类视图

实现

class State;
class LowState; //低等折扣
class MediaState; //中等折扣
class HighState; //高等折扣
//折扣
class Discount
{
public:
Discount(State* sta):m_state(sta){}
~Discount(){delete State;}
void request(){ m_state->handle(this);}
void setstate(State* sta)
{
delete m_state;
m_state = sta;
}
int GetBuyNum(){return m_nBuyNum;}
void SetBuyNum(int nNum){m_nBuyNum =nNum; }
private:
State* m_state;
int m_nBuyNum;
}; //运行系统
class State
{
public:
virtual void handle(Discount*)=0;
}; class LowState : public State
{
public:
LowState();
~ LowState();
void handle(Discount* pDis)
{
if (pDis)
{
int nNum = pDis->GetBuyNum();
if (nNum<=10)
{
cout<< "打9折";
}
else
{
pDis->setstate(new MediaState());
pDis->request();
}
}
}
}; class MediaState : public State
{
public:
MediaState();
~ MediaState();
void handle(Discount* pDis)
{
if (pDis)
{
int nNum = pDis->GetBuyNum();
if(nNum<=10)
{
pDis->setstate(new LowState());
pDis->getstate();
}
else if (nNum>10 && nNum <=50)
{
cout<< "打7折";
}
else
{
pDis->setstate(new HighState());
pDis->request();
}
}
} }; class HighState : public State
{
public:
void handle(Discount* pDis)
{
if (pDis)
{
int nNum = pDis->GetBuyNum();
if (nNum>50)
{
cout<< "打5折";
}
else
{
pDis->setstate(new MediaState());
pDis->request();
}
}
}
}; int main()
{ Discount disc(new LowState());
disc.SetBuyNum(40);
disc.request(); }

状态模式里可以看到策略模式和责任链模式的影子,从结构和功能上会有些相似;

策略模式和状态模式最为相像,其二者主要区别是策略模式更关心的是strategy的类型多态实现,一般会在外部调用时进行指明;而状态模式不会直接决定State的具体实现,而是通过内部状态参数来决定。

责任链模式由前后的链条关系,在创建时需要明确指出,而状态模式是由状态选择其多态的实现。

所以状态模式之所以单独独立出来,就是为了凸显在不同状态下的不同实现。

这篇电梯的实现很形象,大家可以参考电梯应用

应用场景

  1. 一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
  2. 一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态。

设计模式之状态模式(State )的更多相关文章

  1. 【转】设计模式 ( 十七) 状态模式State(对象行为型)

    设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...

  2. 设计模式 ( 十七) 状态模式State(对象行为型)

    设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...

  3. 乐在其中设计模式(C#) - 状态模式(State Pattern)

    原文:乐在其中设计模式(C#) - 状态模式(State Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 状态模式(State Pattern) 作者:webabcd 介绍 允 ...

  4. 北风设计模式课程---状态模式State(对象行为型)

    北风设计模式课程---状态模式State(对象行为型) 一.总结 一句话总结: 状态模式 具体状态的行为在具体的状态类中就解决,不用交给外部做判断.实质是将多条件判断弄成了多个类,在不同的类中做判断 ...

  5. 二十四种设计模式:状态模式(State Pattern)

    状态模式(State Pattern) 介绍允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它所属的类. 示例有一个Message实体类,对它的操作有Insert()和Get()方法, ...

  6. 设计模式2——状态模式State

    参考链接: 设计模式之状态模式:https://www.cnblogs.com/haoerlv/p/7777789.html 设计模式系列之状态模式:https://www.jianshu.com/p ...

  7. 设计模式之 -- 状态模式(State)

     状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类.当控制一个对象的状态转换条件分支语句(if...else或switch...case)过于复杂时,可以此模式将状态的判断逻辑 ...

  8. [设计模式] 20 状态模式 State Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对状态模式是这样说的:允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类.状态模式的重点在于状态转换,很多时候,对 ...

  9. 设计模式之状态模式(State)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  10. 大熊君说说JS与设计模式之------状态模式State

    一,总体概要 1,笔者浅谈 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式. 状态模式主要解决的是当控制一个对象状态的条件表达式过于 ...

随机推荐

  1. Flask实例化的参数 及 对app的配置

    首先展示一下: from flask import Flask app = Flask(__name__) # type:Flask app.config["DEBUG"] = T ...

  2. springmvc接受及响应ajax请求。 以及@RequestBody 和@ResponseBody注解的使用

    1.发送ajax请求 $.ajax({ url:"user/testAjax", contentType:"application/json;charset=UTF-8& ...

  3. 处理返回键劫持(结合vue)

    在这里记录一下近期解决的一个问题 需求,在某个页面,浏览器返回按钮点击的时候,不能走浏览器的默认返回操作,而是要走自己的逻辑, 比如跳转页面等等. 那么问题来了,如何去不走默认返回呢.经过网上搜罗和同 ...

  4. Angular使用总结 --- 如何正确的操作DOM

    无奈接手了一个旧项目,上一个老哥在Angular项目中大量使用了JQuery来操作DOM,真的是太不讲究了.那么如何优雅的使用Angular的方式来操作DOM呢? 获取元素 1.ElementRef  ...

  5. python基础的几个小练习题

    题目: 1.写一个程序,判断2008年是否是闰年. 2.写一个程序,用于计算2008年10月1日是这一年的第几天?(2008年1月1日是这一年的第一天) 3.(文件题)有一个“record.txt”的 ...

  6. 【leetcode】20.有效的括号

    题目 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效.有效字符串需满足:左括号必须用相同类型的右括号闭合.左括号必须以正确的顺序闭合.注意空字符串可被认为 ...

  7. 用synchronized同时修饰父类和子类,线程是安全的。即对象锁可重入

    public class SyncDubbo { static class Main { public int i = 10; public synchronized void operationSu ...

  8. MapReduce对交易日志进行排序的Demo(MR的二次排序)

    1.日志源文件 (各个列分别是: 账户,营业额,花费,日期) zhangsan@163.com 6000 0 2014-02-20 lisi@163.com 2000 0 2014-02-20 lis ...

  9. 一个关于margin-top的问题

    两个 此时内部div的样式为 当我把margin选中 如图所示: 我想要的效果是子div离父div有一个20px的间隙,但显然现在不是我想要的结果, 然后就开始查资料: 这个“问题”……它是CSS2. ...

  10. android 中的Http请求类HttpUrlConnection和HttpClient类

    Android系统提供了两种HTTP通信类,HttpURLConnection和HttpClient. 如何选择这两个类的使用:android-developers.blogspot.com/2011 ...