博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
步步为营 .NET 设计模式学习笔记 八、State(状态模式)
阅读量:6146 次
发布时间:2019-06-21

本文共 5298 字,大约阅读时间需要 17 分钟。

概述

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。

意图

状态模式主要解决的是当控制一个对象状态装换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简单化。

当一个对象行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。

<Design Pattern>State模式结构图

示例关系图

描述:   一年有12个月,有四个季度,每个月都有一属于一个季度,根据月份得到这个季度的天气信息.可以用State模式来实现.

关系图:

代码设计:

先创建接口IQuarter.cs:

public interface  IQuarter    {        ///         /// 通过月份获取季度        ///         ///         /// 
Quarter GetQuarter(); /// /// 气候条件 /// ///
string Climate(); }

再创建Quarter.cs:

public abstract class Quarter:IQuarter    {        private int _Month = 0;        public int Month        {            get            {                return _Month;            }            set            {                _Month = value;            }        }       public Quarter(int month )       {           this.Month = month;       }        #region IQuarter 成员       public abstract Quarter GetQuarter();       public abstract string Climate();        #endregion           }
再创建Spring.cs:
public class Spring : Quarter    {        private Quarter quarter;        public override string Climate()        {            return "春风宜人,鸟语花香,正是旅游的好季节。";        }        public override Quarter GetQuarter()        {            if (Month > 3)            {                quarter = new Summer(Month);                return quarter.GetQuarter();            }            return new Spring(Month);        }        public Spring(int month):base(month)        {                  }    }

再创建Summer.cs:

public class Summer : Quarter    {        private Quarter quarter;        public override string Climate()        {            return "夏季天气炎热,酷暑难熬.";        }        public override Quarter GetQuarter()        {            if (Month < 4)            {                quarter = new Spring(Month);                return quarter.GetQuarter();            }            if (Month > 6)            {                quarter = new Autumn(Month);                return quarter.GetQuarter();            }            return new  Summer(this.Month);        }        public Summer(int month): base(month)        {                   }    }

再创建 Autumn.cs:

public class Autumn : Quarter    {        private Quarter quarter;        public override string Climate()        {            return "秋高气爽.";        }        public override Quarter GetQuarter()        {            if (Month < 7)            {                quarter = new Summer(Month);                return quarter.GetQuarter();            }            if (Month > 9)            {                quarter = new Winter(Month);                return quarter.GetQuarter();            }           return  new Autumn(Month);                    }        public Autumn(int month):base(month)        {                   }    }

再创建Winter.cs:

public class Winter : Quarter    {        private Quarter quarter;        public override string Climate()        {            return "冬天风寒,空气干燥.";        }        public override Quarter GetQuarter()        {            if (Month < 10)            {                return quarter.GetQuarter();                quarter = new Autumn(Month);            }            return new Winter(Month);                   }        public Winter(int month):base(month)        {                   }    }

再创建MonthInfo.cs:

public  class MonthInfo    {       private  Quarter quarter;       public MonthInfo(int month)       {           //初始化为春季           quarter = new Spring(month);                    quarter = quarter.GetQuarter();       }       public string ShowInfo()       {           if (CheckMonthInfo())           {               return GetQuarterClimate();           }           else           {               return GetError();           }       }       private string GetQuarterClimate()       {           return string.Format("月份是:{0}月份,气候是:{1}", this.quarter.Month.ToString(), this.quarter.Climate());       }       private string GetError()       {           return string.Format("月份是:{0},是一个错误的信息.", this.quarter.Month.ToString());       }       private bool CheckMonthInfo()       {           if (this.quarter.Month > 12 || this.quarter.Month < 1)           {               return false;           }           return true;       }    }

再调用它:

public partial class Run : Form    {        public Run()        {            InitializeComponent();        }        private void btnRun_Click(object sender, EventArgs e)        {            for (int i = 0; i < 15; i++)            {                MonthInfo monthInfo = new MonthInfo(i);                rtbResult.AppendText(monthInfo.ShowInfo()+"\n");            }        }    }

结果如图:

 

何时采用

1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。2.一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常,有多个操作包含这
一相同的条件结构。state模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不
依赖于其他对象而独立变化。

3.从代码角度来说,如果一个类有多种状态,并且在类内部通过的条件语句判断的类状态来实现不同行为时候可以把这些行为单独封装为状态类。

4.从应用角度来说,如果一个对象有多种状态,如果希望把对象状态的转化以及由不同状态产生的行为交给具体的状态类去做,那么可以考虑状态模式。

效果及实现要点 

1.在环境角色中拥有状态角色的实例。

2.在状态角色中拥有环境角色的实例用于在具体状态中修改环境角色的状态。

3.状态对象之间的依赖可以通过加载外部配置的转化规则表等方法来消除。

4.状态模式和策略模式的主要区别是,前者的行为实现方式是由条件决定的,并且应当能不在客户端干预的情况下自己迁移到合适的状态,而后者的行为实现方式是由客户端选择的,并且能随时替换。

总结

1.优点: 避免了为判断状态而产生的巨大的if或case语句。 将对象行为交给状态类维护后,对于上层程序而言,仅需要维护状态之间的转换规则。

2.缺点:会导致某些系统有过多的具体状态类。

 

3.过多的状态对象可能会增加系统负担,可以考虑把各种状态角色实现为无状态对象的享元,需要保存的额外状态由环境角色进行统一管理和处理。

转载地址:http://cnmya.baihongyu.com/

你可能感兴趣的文章
《图解HTTP》1~53Page Web网络基础 HTTP协议 HTTP报文内的HTTP信息
查看>>
unix环境高级编程-高级IO(2)
查看>>
树莓派是如何免疫 Meltdown 和 Spectre 漏洞的
查看>>
雅虎瓦片地图切片问题
查看>>
HTML 邮件链接,超链接发邮件
查看>>
HDU 5524:Subtrees
查看>>
手机端userAgent
查看>>
pip安装Mysql-python报错EnvironmentError: mysql_config not found
查看>>
http协议组成(请求状态码)
查看>>
怎样成为一个高手观后感
查看>>
[转]VC预处理指令与宏定义的妙用
查看>>
JQuery radio单选框应用
查看>>
MySql操作
查看>>
python 解析 XML文件
查看>>
MySQL 文件导入出错
查看>>
java相关
查看>>
由一个异常开始思考springmvc参数解析
查看>>
向上扩展型SSD 将可满足向外扩展需求
查看>>
jenkins updatecenter更新插件有问题
查看>>
我的友情链接
查看>>