内容简介:你是否经常请(】。在这不同的状态是可以有不同的操作的。
一、定义
你是否经常请( 偷 )假( 懒 )?是不是对公司万恶的请假申请流程深 恶 痛绝 。有没有想过偷偷改造这个万恶的系统,从 申请->项目经理审批->部门审批->老板审批->完成 偷偷改为 申请->完成。为了实现这个正义[ 偷笑 ]又合理的诉求,你得先学会今天要介绍的设计模式,因为你们公司的这个流程可能就是用今天这个模式设计的。来看看这个 设计模式 是怎么来抽象这类流程性的业务的。
状态模式【百度百科】 :当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
这个定义看起来莫名其妙,咋一看,我也不知道它要表达什么。个人的理解:某个对象是有状态的,比如我们上面的请假流程,它处于项目经理状态,那项目经理可以审核你的请假申请,到了老板处理环节,老板直接把你申请单删了【 哈哈】。在这不同的状态是可以有不同的操作的。
不知道你看懂了定义了没??什么?没看懂,那就直接看下面的代码咯,talk is cheap show me the code。
二、UML图
UML图如下,我直接把请假这个例子画了个UML图,如下,有一个 公共的State抽象类 ,里面定义了两个变量来保存当前状态的状态Code,状态Name,下面为 具体的状态 ,分别为:AppState(申请状态),ProjectManagesState(项目经理审核状态),BossState(老板审核状态),通过Context来提供给客户端使用。
三、请假流程实现
具体代码实现如下:
1、状态抽象类
package com.design.state;
public abstract class State {
private String stateCode;
private String stateName;
//往下个环节走
public abstract void toNextState(Context context);
public State(String stateCode, String stateName){
this.stateCode = stateCode;
this.stateName = stateName;
}
public String getStateCode() {
return stateCode;
}
public void setStateCode(String stateCode) {
this.stateCode = stateCode;
}
public String getStateName() {
return stateName;
}
public void setStateName(String stateName) {
this.stateName = stateName;
}
}
复制代码
2、定义具体的状态
package com.design.state;
/**
* 申请状态
*/
public class AppState extends State{
public AppState(){
super("Apply", "申请环节");
}
@Override
public void toNextState(Context context) {
//申请状态,这里可以做该状态下的操作
System.out.println("我是申请人,我申请休假,下一个环节是项目经理审核!!");
//直接进去项目经理审核状态
context.setCurrentState(new ProjectManagesState());
}
}
复制代码
package com.design.state;
/**
* 项目经理审核状态
*/
public class ProjectManagesState extends State{
public ProjectManagesState(){
super("ProjectManages", "项目经理审核环节");
}
@Override
public void toNextState(Context context) {
//项目经理审核状态,这里可以做该状态下的操做
System.out.println("我是项目经理,那臭小子一定有跑去面试了,哎,帮他一把,同意了,下个环节让老板审去");
//直接进去老板审核状态
context.setCurrentState(new BossState());
}
}
复制代码
package com.design.state;
/**
* 老板审核状态
*/
public class BossState extends State{
public BossState(){
super("Boss Audit", "老板审核环节");
}
@Override
public void toNextState(Context context) {
//项目经理审核状态,这里可以做该状态下的操做
System.out.println("我是老板,我同意你请假了!!!流程结束!");
}
}
复制代码
3、上下文类
package com.design.state;
public class Context {
private State currentState;
public Context(State state){
currentState = state;
}
public void toNextState(){
currentState.toNextState(this);
};
public State getCurrentState() {
return currentState;
}
public void setCurrentState(State currentState) {
this.currentState = currentState;
}
}
复制代码
4、写好了,看下怎么调用
package com.design.state;
public class TestMain {
public static void main(String[] args) {
//创建申请休假单
Context context = new Context(new AppState());
System.out.println("状态:"+context.getCurrentState().getStateName());
//提交申请
context.toNextState();
System.out.println("状态:"+context.getCurrentState().getStateName());
//项目经理审核
context.toNextState();
System.out.println("状态:"+context.getCurrentState().getStateName());
//老板审核
context.toNextState();
}
}复制代码
5、执行结果
五、优缺点
1、优点
(1)、将与特定状态相关的行为局部化,将不同状态的行为分割开来。
(2)、把状态转移逻辑分布到具体状态类中,减少相互间的依赖。
看不懂这两个优点??OK,我们来解释下,先来看看,不用状态模式,我们代码会怎么写?
package com.design.state;
public class StateChange {
private int state = 0;
private final static int APPLY=0; //申请状态
private final static int PROJECTMANAGES=1;//项目经理审核状态
private final static int BOSS=2;//老板审核状态
private final static int FINISH=3;//流程结束状态
public void toNextState(){
switch (state){
case 0:
//申请状态,做点操作
System.out.println("写申请书!!!");
//进入项目经理审核状态
state = PROJECTMANAGES;
break;
case 1:
System.out.println("项目经理审核,同意你申请了");
//进入老板审核状态
state = BOSS;
break;
case 2:
System.out.println("我是老板,同意你申请了");
//进入结束状态
state = FINISH;
break;
default:
break;
}
}
}复制代码
你是不是写的跟我一样呢??有没有注意到,所有的操作,无论是哪个状态的操作都是在这个类中完成的,而使用状态模式,不同状态下的行为是定义在不同的状态类下的。这就是前面说的优点1。
我们状态切换是通过switch来判断状态,再决定下一个状态的,而在状态模式下,切换到下一个状态,是在具体的状态类下进行的,可以减少if之类的判断逻辑。这就是优点2。
2、缺点
(1)、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
(2)、状态模式对"开闭原则"的支持并不太好,新增状态时,不仅得增加状态类,还得修改原来已经有的状态,让之前的状态切换到新增的状态。
六、总结说明
状态模式将原来通过判断实现的状态切换分散到各具体状态类中,比如上面切换到“老板审核状态”,是在“项目经理审核状态”中进行的,当状态比较多的情况,不容易理清各状态切换关系。同时它有将各状态的操作独立到状态类中,方便测试,还有分隔开各不同操作,便于阅读代码。实际运用中可根据自己的场景进行权衡。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 设计模式——订阅模式(观察者模式)
- 设计模式-简单工厂、工厂方法模式、抽象工厂模式
- java23种设计模式-门面模式(外观模式)
- 设计模式-享元设计模式
- Java 设计模式之工厂方法模式与抽象工厂模式
- JAVA设计模式之模板方法模式和建造者模式
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Python金融大数据分析
[德] 伊夫·希尔皮斯科 / 姚军 / 人民邮电出版社 / 2015-12 / CNY 99.00
唯一一本详细讲解使用Python分析处理金融大数据的专业图书;金融应用开发领域从业人员必读。 Python凭借其简单、易读、可扩展性以及拥有巨大而活跃的科学计算社区,在需要分析、处理大量数据的金融行业得到了广泛而迅速的应用,并且成为该行业开发核心应用的首选编程语言。《Python金融大数据分析》提供了使用Python进行数据分析,以及开发相关应用程序的技巧和工具。 《Python金融大......一起来看看 《Python金融大数据分析》 这本书的介绍吧!