【设计模式】状态(State)模式

状态模式主要解决的是当控制一个对象状态转换的条侏表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的系列类当中,可以把复杂的逻辑简化。

状态模式

  • 允许一个对象在其内部状态改变时改变它的行为,这个对象看起来似乎修改了它的类。
  • 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表系不同状态的一系列类当中,可以把复杂的逻辑简化。
  • 每个人、事务在不同的状态下会有不同表现动作,而一个状态又会在不同的表现下转移到写一个不同的状态。
  • 在State模式中我们将状态逻辑和动作实现进行分离。当一个操作中要维护大量的分支语句,并且这些分支依赖于对象的状态。State模式将每一个分支都封装到独立的类中。

State模式结构

【设计模式】状态(State)模式_第1张图片

优点

  • 将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
  • 消除庞大的条件分支语句,把各种状态转移逻辑分布到State的子类之间,减少了相互间的依赖。
  • 显式化进行状态转换:为不同的状态引入独立的对象,使得状态的转换变得更如明确。而且状态对象可以保证上下文不会发生内部状态不一致的状况,因为上下文中只有一个变量来记录状态对象,只要为这一个变量赋值就可以了。

缺点

State模式问题主要是逻辑分散化,状态逻辑分布到了很多的State的子类中,很难看到整个的状态逻辑图,这也带来了代码的维护问题。

本质

  • 根据状态来分离和选择行为
  • 状态模式是状态驱动,由上下文负责。

State模式和Strategy模式简单对比

  • State模式和Strategy模式有很大程度上的相似:它们都有-一个Context类,都是通过委托(组合)给一个具有多个派生类的多态基类实现Context的算法逻辑。
  • 两者最大的差别就是State模式中派生类持有指向Context对象的引用,并通过这个引用调用Context中的方法,但在Strategy模式中就没有这种情况。

实例

【问题】
工作流中的请假流程:

  • 某人提出请假申请,先由项目经理审批,如果项目经理不同意,审批就直接结束。
  • 如项目经理同意,再看是否超过3天,如果三天以内,审批直接结束。
  • 否则,交给部门经理,部门络理审核后,无论是否同意,审批直接结束。

【代码】

package Leave_StateMode;

public class Context {
	
	private State st;
	private int days;
	private String name;
	private boolean ProjectManager,DepartmentManager;
	
	public Context() {
		st=new ProjectAccept();
	}

	public Context(int days, String name, boolean projectManager, boolean departmentManager) {
		super();
		this.days = days;
		this.name = name;
		ProjectManager = projectManager;
		DepartmentManager = departmentManager;
		st=new ProjectAccept();
	}

	public State getSt() {
		return st;
	}

	public void setSt(State st) {
		this.st = st;
	}

	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 void setDepartmentManager(boolean departmentManager) {
		DepartmentManager = departmentManager;
	}
	
	public void leave() {
		st.leave(this);
	}

}

package Leave_StateMode;

public abstract class State {
	
	public abstract void leave(Context con);

}
package Leave_StateMode;

public class ProjectAccept extends State {

	@Override
	public void leave(Context con) {
		if(con.isProjectManager()==false) {
			System.out.println("项目经理不同意!"+con.getName()+"的请假审批不通过!");
		}else {
			ThreeDaysLess tdl=new ThreeDaysLess();
			tdl.leave(con);
		}
	}

}

package Leave_StateMode;

public class ThreeDaysLess extends State {

	@Override
	public void leave(Context con) {
		if(con.getDays()<=3) {
			System.out.println("项目经理同意!"+con.getName()+"的请假审批通过!共请假"+con.getDays()+"天!");
		}else {
			System.out.println("请假时间超过三天,请移至部门经理处!");
			ThreeDaysOver tdo=new ThreeDaysOver();
			tdo.leave(con);
		}

	}

}

package Leave_StateMode;

public class ThreeDaysOver extends State {

	@Override
	public void leave(Context con) {
		if(con.isDepartmentManager()==true) {
			System.out.println("项目经理同意!部门经理同意!"+con.getName()+"的请假审批通过!共请假"+con.getDays()+"天!");
		}else {
			System.out.println("项目经理同意!部门经理不同意!"+con.getName()+"的请假审批不通过!");
		}
	}

}

package Leave_StateMode;

public class Client {

	public static void main(String[] args) {
		Context con = new Context();
		con.setName("小菜");
		con.setDays(4);
		con.setProjectManager(true);
		con.setDepartmentManager(true);
		con.leave();
	}

}

【UML图】
【设计模式】状态(State)模式_第2张图片

你可能感兴趣的:(设计模式)