状态模式
- 允许一个对象在其内部状态改变时改变它的行为,这个对象看起来似乎修改了它的类。
- 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表系不同状态的一系列类当中,可以把复杂的逻辑简化。
- 每个人、事务在不同的状态下会有不同表现动作,而一个状态又会在不同的表现下转移到写一个不同的状态。
- 在State模式中我们将状态逻辑和动作实现进行分离。当一个操作中要维护大量的分支语句,并且这些分支依赖于对象的状态。State模式将每一个分支都封装到独立的类中。
State模式结构
优点
- 将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
- 消除庞大的条件分支语句,把各种状态转移逻辑分布到State的子类之间,减少了相互间的依赖。
- 显式化进行状态转换:为不同的状态引入独立的对象,使得状态的转换变得更如明确。而且状态对象可以保证上下文不会发生内部状态不一致的状况,因为上下文中只有一个变量来记录状态对象,只要为这一个变量赋值就可以了。
缺点
State模式问题主要是逻辑分散化,状态逻辑分布到了很多的State的子类中,很难看到整个的状态逻辑图,这也带来了代码的维护问题。
本质
- 根据状态来分离和选择行为
- 状态模式是状态驱动,由上下文负责。
State模式和Strategy模式简单对比
- State模式和Strategy模式有很大程度上的相似:它们都有-一个Context类,都是通过委托(组合)给一个具有多个派生类的多态基类实现Context的算法逻辑。
- 两者最大的差别就是State模式中派生类持有指向Context对象的引用,并通过这个引用调用Context中的方法,但在Strategy模式中就没有这种情况。
实现
public abstract class State {
public abstract void Handle(Context context);
}
public class ConcreteStateA extends State{
@Override
public void Handle(Context context) {
context.setState(new ConcreteStateB()); //设置A的下一个状态是B
}
}
class ConcreteStateB extends State{
@Override
public void Handle(Context context) {
context.setState(new ConcreteStateC()); //设置B的下一个状态是C
}
}
class ConcreteStateC extends State{
@Override
public void Handle(Context context) {
context.setState(new ConcreteStateA()); //设置C的下一个状态是A
}
}
public class Context {
State state;
public Context(State state) { //定义Context的初始状态
super();
this.state = state;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
System.out.println("当前状态为"+state);
}
public void request(){
state.Handle(this); //对请求做处理并且指向下一个状态
}
}
实例
【问题】
工作流中的请假流程:
- 某人提出请假申请,先由项目经理审批,如果项目经理不同意,审批就直接结束。
- 如项目经理同意,再看是否超过3天,如果三天以内,审批直接结束。
- 否则,交给部门经理,部门络理审核后,无论是否同意,审批直接结束。
package 状态模式;
public class Context {
private State st;
private int days;
private String name;
private String pro;
private String dept;
private boolean ProjectManager,DepartmentManager,BossManager;
public Context(int days, String name, String pro, String dept, boolean projectManager, boolean departmentManager,
boolean boss) {
super();
this.days = days;
this.name = name;
this.pro = pro;
this.dept = dept;
ProjectManager = projectManager;
DepartmentManager = departmentManager;
this.BossManager = boss;
}
public boolean isBossManager() {
return BossManager;
}
public void setBossManager(boolean bossManager) {
BossManager = bossManager;
}
public Context( int days, String name, String pro, String dept, boolean projectManager,
boolean departmentManager) {
super();
this.days = days;
this.name = name;
this.pro = pro;
this.dept = dept;
ProjectManager = projectManager;
DepartmentManager = departmentManager;
}
public Context() {
super();
// TODO Auto-generated constructor stub
}
public int getDays() {
return days;
}
public void setDays(int days) {
this.days = days;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isProjectManager() {
return ProjectManager;
}
public void setProjectManager(boolean projectManager) {
ProjectManager = projectManager;
}
public boolean isDepartmentManager() {
return DepartmentManager;
}
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
public String getPro() {
return pro;
}
public void setPro(String pro) {
this.pro = pro;
}
public void setDepartmentManager(boolean departmentManager) {
DepartmentManager = departmentManager;
}
public void leave() {
st.leave(this);
}
}
package 状态模式;
public abstract class State {
public abstract void leave(Context con);
}
package 状态模式;
public class Accept extends State {
@Override
public void leave(Context con) {
if(con.isProjectManager()==false) {
System.out.println(con.getPro()+"经理不同意请假!"+con.getName()+"的请假");
}else {
Less3 tdl=new Less3();
tdl.leave(con);
}
}
}
package 状态模式;
public class Less3 extends State {
@Override
public void leave(Context con) {
if(con.getDays()<=3) {
System.out.println(con.getPro() +"项目经理同意!"+con.getName()+"的请假审批通过!共请假"+con.getDays()+"天!");
}else {
System.out.println("请假时间超过三天,请移至"+con.getDept()+"部门经理处!");
More3_Less7 tdo=new More3_Less7();
tdo.leave(con);
}
}
}
package 状态模式;
public class More3_Less7 extends State {
@Override
public void leave(Context con) {
if(con.getDays()<=7) {
System.out.println(con.getDept()+"部门经理同意!"+con.getName()+"的请假审批通过!共请假"+con.getDays()+"天!");
}else {
System.out.println("请假时间超过7天,请移至总经理!");
More7 tdo=new More7();
tdo.leave(con);
}
}
}
package 状态模式;
public class More7 extends State {
@Override
public void leave(Context con) {
if(con.isBossManager()==true) {
System.out.println(con.getPro()+"项目经理同意!"+con.getDept()+"部门经理同意!总经理同意!"+con.getName()+"的请假审批通过!共请假"+con.getDays()+"天!");
}else {
System.out.println(con.getPro()+"项目经理同意!"+con.getDept()+"部门经理同意!总经理不同意!"+con.getName()+"的请假审批不通过!");
}
}
}
package 状态模式;
public class Client {
public static void main(String[] args) {
Context con = new Context(8,"菜鸡","设计模式","设计",true,true,true);
con.setName("菜鸡");
con.setPro("设计模式");
con.setDept("设计");
con.setDays(8);
con.setProjectManager(true);
con.setDepartmentManager(true);
con.leave();
}
}