系列文章目录
创建型模式 - 单例模式(一)
创建型模式 - 工厂模式(二)
创建型模式 - 原型模式(三)
创建型模式 - 建造者模式(四)
结构型模式 - 适配器模式(一)
结构型模式 - 桥接模式(二)
结构型模式 - 装饰器模式(三)
结构型模式 - 组合模式(四)
结构型模式 - 外观模式(五)
结构型模式 - 享元模式(六)
结构型模式 - 代理模式(七)
行为型模式 - 模板方法模式(一)
行为型模式 - 命令模式(二)
行为型模式 - 访问者模式(三)
行为型模式 - 迭代器模式(四)
行为型模式 - 观察者模式(五)
行为型模式 - 中介者模式(六)
行为型模式 - 备忘录模式(七)
行为型模式 - 解释器模式(八)
行为型模式 - 状态模式(九)
行为型模式 - 策略模式(十)
行为型模式 - 责任链模式(十一)
文章目录
前言
一、状态模式
1.1 状态模式介绍
- 状态(State)模式:
- 一个对象的行为取决于内部一个 或者多个动态变化的属性,并且可以灵活地切换状态;
- 对于有状态的对象,把复杂的 “判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为;
1.2 状态模式结构
环境类(Context)角色:
- 定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换;
抽象状态(State)角色:
- 定义了一个接口,用以封装环境对象中特定状态所对应的行为,可以有一个或者多个行为;
具体状态(Concrete State)角色:
- 实现抽象状态所对应的行为,并且在需要的情况下进行状态的切换;
二、实现
例子:
- 张三第一天去中南海上班,心里高高兴兴,做什么都积极,第二天去上班的路上被李四和王五打了,一天上班都无精打采,第三天去上班,领导被免职了,张三一天啥也没干;
2.1 状态模式实现
package com.dozezz.designpattern.state;
/**
* 抽象状态类
*/
public interface State {
void handle(Context context);
}
package com.dozezz.designpattern.state;
/**
* 具体状态类
*/
public class HappyState implements State{
@Override
public void handle(Context context) {
System.out.println("上班了,各种积极主动干活。。");
context.changeState(new AngryState());
}
}
package com.dozezz.designpattern.state;
/**
* 具体状态类
*/
public class AngryState implements State{
@Override
public void handle(Context context) {
System.out.println("无缘无故被打,还有没有天理,研究研究怎么找回场子。。");
context.changeState(new SadState());
}
}
package com.dozezz.designpattern.state;
/**
* 具体状态类
*/
public class SadState implements State{
@Override
public void handle(Context context) {
System.out.println("老领导对我们那么好,为啥被免职了,没心情干活。。");
}
}
package com.dozezz.designpattern.state;
/**
* 环境类
*/
public class Context {
private State state;
public void changeState(State state){
this.state = state;
}
public void doSomething(){
state.handle(this);
}
public void setState(State state) {
this.state = state;
}
}
package com.dozezz.designpattern.state;
/**
* 主测试类
*/
public class ClientTest {
public static void main(String[] args) {
Context context = new Context();
context.setState(new HappyState());
context.doSomething();
context.doSomething();
context.doSomething();
}
}
三、状态模式总结
3.1 状态的应用场景
- 当一个事件或对象有很多种状态,状态之间会互相转换,对不同的状态有不同的行为的时候;
3.2 状态模式、策略模式区别
- 状态模式和策略模式的UML类图架构几乎完全一样,但是两者的应用场景不一样
- 策略模式的多种算法行为择其一都能满足,彼此之间独立的,用户可自行更换策略算法,而状态模式的各个状态间存在相互关系,彼此之间在一定条件下存在自动切换状态的效果,并且用户无法指定状态,只能设置初始状态;
3.3 状态模式、责任链模式区别
- 状态模式和责任链模式都能消除if-else 分支过多的问题,但在某些情况下,状态模式中的状态可以理解为责任,那么在这种情况下,两种模式都可以使用;
- 状态模式强调的是一个对象内在状态的改变,而责任链模式强调的是外部节点对象间的改变;
- 从代码层面实现看,两者最大的区别就是状态模式的各个状态知道自己要进入的下一个状态对象,而责任链模式并不清楚其下一个节点对象,因为链式组装由客户端负责;
3.4 状态模式总结
- 状态模式的重点就是将对象的状态切换以及不同状态具有不同行为与客户端进行解耦,不同的状态类型组成了状态的体系结构,Context封装了切换逻辑,可以做到状态的切换对客户端透明;
- 状态模式必然导致大量的状态类出现,如果状态很少,可能不会用状态模式,而且运行时的对象个数也会增加;
- 如果增加新的状态类,对于那些涉及状态切换的代码笔谈修改,不符合开闭原则;
四、参考文献
- http://c.biancheng.net/view/1390.html
- https://www.cnblogs.com/noteless/p/10178477.html
- https://www.bilibili.com/video/BV1G4411c7N4?p=54&spm_id_from=pageDriver