JAVA语言之23种设计模式(22)-状态模式
龚超 2018-05-04 来源 : 阅读 831 评论 0

摘要:JAVA语言状态模式概述当系统中某个对象存在多个状态,这些状态之间可以进行转换,而且对象在不同状态下行为不相同时可以使用状态模式。状态模式将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象状态可以灵活变化。状态模式是一种对象行为型模式。希望对大家学习JAVA语言有所帮助。

23种设计模式(22)-状态模式

 

一、概述

    当系统中某个对象存在多个状态,这些状态之间可以进行转换,而且对象在不同状态下行为不相同时可以使用状态模式。状态模式将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象状态可以灵活变化。状态模式是一种对象行为型模式。

 

二、适用场景

    用于解决系统中复杂对象的多种状态转换以及不同状态下行为的封装问题。简单说就是处理对象的多种状态及其相互转换。

 

三、UML类图

 

JAVA语言之23种设计模式(22)-状态模式 

四、参与者

1>、AbstractState(抽象状态类):

        在抽象状态类中定义申明了不同状态下的行为抽象方法,而由子类(不同的状态子类)中实现不同的行为操作。

2>、ConcreteState(实现具体状态下行为的状态子类):

        抽象状态类的子类,每一个子类实现一个与环境类(Context)的一个状态相关的行为,每一个具体的状态类对应环境的一种具体状态,不同的具体状态其行为有所不同。

3>、Context(拥有状态对象的环境类):

        拥有状态属性,因环境的多样性,它可拥有不同的状态,且在不同状态下行为也不一样。在环境类中维护一个抽象的状态实例,这个实例定义当前环境的状态(setState()方法),而将具体的状态行为分离出来由不同的状态子类去完成。

 

五、用例学习

1、抽象状态类:State.java

/** * JAVA设计模式之 状态模式 * 抽象状态类 * @author  lvzb.software@qq.com * */  public abstract class State {     /**     * 状态行为抽象方法,由具体的状态子类去实现不同的行为逻辑     */     public abstract void Behavior();   }

2、具体状态子类A:ConcreteStateA.java

/** 
* 具体的状态子类A 
* @author  lvzb.software@qq.com 
*/  
public class ConcreteStateA extends State {  
 
   @Override  
   public void Behavior() {  
       // 状态A 的业务行为, 及当为该状态下时,能干什么   
       // 如:手机在未欠费停机状态下, 能正常拨打电话  
       System.out.println("手机在未欠费停机状态下, 能正常拨打电话");  
   }  
 
}

 

3、具体状态子类B:ConcreteStateB.java

/** 
* 具体的状态子类B 
* @author  lvzb.software@qq.com 
* 
*/  
public class ConcreteStateB extends State {  
 
   @Override  
   public void Behavior() {  
       // 状态B 的业务行为, 及当为该状态下时,能干什么  
       // 如:手机在欠费停机状态下, 不 能拨打电话  
       System.out.println("手机在欠费停机状态下, 不能拨打电话");  
   }  
 
}

 

4、拥有状态对象的环境类:Context.java

/** 
* 环境/上下文类
 
* 拥有状态对象,且可以完成状态间的转换 [状态的改变/切换 在环境类中实现] 
* @author  lvzb.software@qq.com 
* 
*/  
public class Context {  
   // 维护一个抽象状态对象的引用  
   private State state;  
     
   /* 
    * 模拟手机的话费属性
 
    * 环境状态如下: 
    * 1>、当  bill >= 0.00$ : 状态正常   还能拨打电话  
    * 2>、当  bill < 0.00$ : 手机欠费   不能拨打电话 
    */  
   private double bill;  
     
   /** 
    * 环境处理函数,调用状态实例行为 完成业务逻辑
 
    * 根据不同的状态实例引用  在不同状态下处理不同的行为 
    */  
   public void Handle(){  
       checkState();  
       state.Behavior();  
   }  
     
     
   /** 
    * 检查环境状态:状态的改变/切换 在环境类中实现 
    */  
   private void checkState(){  
       if(bill >= 0.00){  
           setState(new ConcreteStateA());  
       } else {  
           setState(new ConcreteStateB());  
       }  
   }  
     
     
   /** 
    * 设置环境状态
 
    * 私有方法,目的是 让环境的状态由系统环境自身来控制/切换,外部使用者无需关心环境内部的状态 
    * @param state 
    */  
   private void setState(State state){  
       this.state = state;  
   }  
 
 
   public double getBill() {  
       return bill;  
   }  
 
   public void setBill(double bill) {  
       this.bill = bill;  
   }  
}

 

5、测试客户端调用类:Client.java

public class Client {  
 
   public static void main(String[] args) {  
       Context context = new Context();  
       context.setBill(5.50);  
       System.out.println("当前话费余额:" + context.getBill() + "$");  
       context.Handle();  
         
       context.setBill(-1.50);  
       System.out.println("当前话费余额:" + context.getBill() + "$");  
       context.Handle();  
         
       context.setBill(50.00);  
       System.out.println("当前话费余额:" + context.getBill() + "$");  
       context.Handle();  
   }  
}

 

6、程序运行结果:

当前话费余额:5.5$  
手机在未欠费停机状态下, 能正常拨打电话  
当前话费余额:-1.5$  
手机在欠费停机状态下, 不能拨打电话  
当前话费余额:50.0$  
手机在未欠费停机状态下, 能正常拨打电话

 

六、扩展

    状态模式中 关于状态的切换有两种不同的实现方式

    方式一:状态的改变/切换  在环境类中实现。  如上面的用例代码Context类中的checkState()方法。

/** 
    * 检查环境状态:状态的改变/切换 在环境类中实现 
   

*/     private void checkState(){         if(bill >= 0.00){             setState(new ConcreteStateA());         } else {             setState(new ConcreteStateB());         }     }

方式二:状态的改变/切换  在具体的状态子类中实现。

        实现步骤如下:

        1> 在环境类Context类中 初始化一个状态实例对象,并将环境Context对象作为子类状态的构造参数传递到具体的状态子类实例中。

       如在Context.java类中

// 设置初始状态  
this.state = new ConcreteStateA(this);

 

2> 在具体的子类状态类中根据构造进来的context对象,通过调用context对象的属性值进行业务逻辑判断 进行状态的检查和切换。

 

如在 具体的状态子类ConcreteStateA.java类中:

/** 
* 具体的状态子类A 
* @author  lvzb.software@qq.com 
*/  
public class ConcreteStateA extends State {  
   private Context ctx;  
     
   public ConcreteStateA(Context context){  
       ctx = context;  
   }
    
   @Override  
   public void Behavior() {  
       // 状态A 的业务行为, 及当为该状态下时,能干什么   
       // 如:手机在未欠费停机状态下, 能正常拨打电话  
       System.out.println("手机在未欠费停机状态下, 能正常拨打电话");  
       checkState();  
         
   }  
 
   /** 
    * 检查状态 是否需要进行状态的转换
 
    * 状态的切换由具体状态子类中实现 
    */  
   private void checkState(){  
       if (ctx.getBill() < 0.00) {  
           ctx.setState(new ConcreteStateB(ctx));  
       }  
   }  
}

如有问题请加微信号:Iotek666,本微信号会不定期推送技术相关优质文章、热点资讯、视频资源及生活趣事,也很乐意与您一起交流IT知识,让我们在闲暇之余巩固一下自己的知识体系 ,扩充一下自己的知识面。快利用琐碎时间给自己充电吧!希望这篇文章可以帮助到你,总之同学们,IT资讯尽在职坐标。


本文由 @职坐标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论
本文作者 联系TA

擅长针对企业软件开发的产品设计及开发的细节与流程设计课程内容。座右铭:大道至简!

  • 370
    文章
  • 23122
    人气
  • 87%
    受欢迎度

已有23人表明态度,87%喜欢该老师!

进入TA的空间
求职秘籍 直通车
  • 索取资料 索取资料 索取资料
  • 答疑解惑 答疑解惑 答疑解惑
  • 技术交流 技术交流 技术交流
  • 职业测评 职业测评 职业测评
  • 面试技巧 面试技巧 面试技巧
  • 高薪秘笈 高薪秘笈 高薪秘笈
TA的其他文章 更多>>
WEB前端必须会的基本知识题目
经验技巧 93% 的用户喜欢
Java语言中四种遍历List的方法总结(推荐)
经验技巧 91% 的用户喜欢
Java语言之SHA-256加密的两种实现方法详解
经验技巧 75% 的用户喜欢
java语言实现把两个有序数组合并到一个数组的实例
经验技巧 75% 的用户喜欢
通过Java语言代码来创建view的方法
经验技巧 80% 的用户喜欢
其他海同师资 更多>>
吕益平
吕益平 联系TA
熟悉企业软件开发的产品设计及开发
孔庆琦
孔庆琦 联系TA
对MVC模式和三层架构有深入的研究
周鸣君
周鸣君 联系TA
擅长Hadoop/Spark大数据技术
范佺菁
范佺菁 联系TA
擅长Java语言,只有合理的安排和管理时间你才能做得更多,行得更远!
金延鑫
金延鑫 联系TA
擅长与学生或家长及时有效沟通
经验技巧30天热搜词 更多>>

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程