博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《设计模式之禅》读书笔记--(21)状态模式
阅读量:4299 次
发布时间:2019-05-27

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

定义

当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。

类图

这里写图片描述

State 抽象状态角色

接口或抽象类,负责对象状态定义,并且封装环境角色以实现状态切换。

ConcreteState 具体状态角色

每一个具体状态必须完成两个职责:本状态的行为管理以及趋向状态处理,通俗地说,就是本状态下要做的事情,以及本状态如何过渡到其他状态。

Context 环境角色

定义客户端需要的接口,并且负责具体状态的切换。

实现

抽象状态角色:

package com.sigalhu.statepattern;public abstract class State {
//定义一个环境角色,提供子类访问 protected Context context; //设置环境角色 public void setContext(Context context){ this.context = context; } //行为1 public abstract void handle1(); //行为2 public abstract void handle2();}

具体状态角色:

package com.sigalhu.statepattern;public class ConcreteState1 extends State {
@Override public void handle1() { //本状态下必须处理的逻辑 } @Override public void handle2() { //设置当前状态为state2 super.context.setCurrentState(Context.STATE2); //过渡到state2状态,由Context实现 super.context.handle2(); }}
package com.sigalhu.statepattern;public class ConcreteState2 extends State {
@Override public void handle1() { //设置当前状态为state1 super.context.setCurrentState(Context.STATE1); //过渡到state1状态,由Context实现 super.context.handle1(); } @Override public void handle2() { //本状态下必须处理的逻辑 }}

环境角色:

package com.sigalhu.statepattern;public class Context {
//定义状态 public final static State STATE1 = new ConcreteState1(); public final static State STATE2 = new ConcreteState2(); //当前状态 private State currentState; //获得当前状态 public State getCurrentState(){ return currentState; } //设置当前状态 public void setCurrentState(State currentState) { this.currentState = currentState; //切换状态 this.currentState.setContext(this); } //行为委托 public void handle1(){ this.currentState.handle1(); } public void handle2(){ this.currentState.handle2(); }}

场景类:

package com.sigalhu.statepattern;public class Client {
public static void main(String[] args){ //定义环境角色 Context context = new Context(); //初始化状态 context.setCurrentState(new ConcreteState1()); //行为执行 context.handle1(); context.handle2(); }}

优点

  • 结构清晰。避免了过多的switch...case或者if...else语句的使用,避免了程序的复杂性,提高系统的可维护性;
  • 遵循设计原则。很好地体现了开闭原则和单一职责原则,每个状态都是一个子类,你要增加状态就要增加子类,你要修改状态,就只要修改一个子类就好了;
  • 封装性非常好。状态变换放置到类的内部来实现,外部的调用不用知道类内部如何实现状态和行为的变换。

缺点

如果完全使用状态模式就会有太多的子类,造成类膨胀,不好管理。

注意

状态模式适用于当某个对象在它的状态发生改变时,它的行为也随着发生比较大的变化,也就是说在行为受状态约束的情况下可以使用状态模式,而且使用时对象的状态最好不要超过5个。

源码:

你可能感兴趣的文章
Hive Beeline使用
查看>>
Centos6安装图形界面(hdp不需要,hdp直接从github上下载数据即可)
查看>>
CentOS7 中把yum源更换成163源
查看>>
关于yum Error: Cannot retrieve repository metadata (repomd.xml) for repository:xxxxxx.
查看>>
linux下载github中的文件
查看>>
HDP Sandbox里面git clone不了数据(HTTP request failed)【目前还没解决,所以hive的练习先暂时搁置了】
查看>>
动态分区最佳实践(一定要注意实践场景)
查看>>
HIVE—索引、分区和分桶的区别
查看>>
Hive进阶总结(听课总结)
查看>>
大数据领域两大最主流集群管理工具Ambari和Cloudera Manger
查看>>
Sqoop往Hive导入数据实战
查看>>
Mysql到HBase的迁移
查看>>
Sqoop import进阶
查看>>
Hive语句是如何转化成MapReduce任务的
查看>>
Hive创建table报错:Permission denied: user=lenovo, access=WRITE, inode="":suh:supergroup:rwxr-xr-x
查看>>
Hive执行job时return code 2排查
查看>>
hive常用函数及数据结构介绍
查看>>
Hive面试题干货(亲自跟着做了好几遍,会了的话对面试大有好处)
查看>>
力扣题解-230. 二叉搜索树中第K小的元素(递归方法,中序遍历解决)
查看>>
力扣题解-123. 买卖股票的最佳时机 III(动态规划)
查看>>