状态模式允许对象在内部状态改变的时候,改变它的行为,对象看起来好像修改了它的类.因为这个模式将状态封装成为独立的类,并将动作委托到代表当前状态的对象,而行为会随着内部状态而改变.
在状态模式中,Context内部持有状态,State接口定义了一个所有具体状态的共同接口,任何状态都实现这个相同的接口,这样一来,各个状态可以互相替换.具体状态实现状态接口,所以当Context改变状态的时候,行为也跟着改变.而不管在什么时候,只要有人调用Context的具体方法,它就会用来委托状态处理,下面用具体事例来说明,Person类代表Context.
public class Person { //给定的三种状态 State happyState=new HappyState(this); State angryState=new AngryState(this); State sadState=new SadState(this); State state=happyState; //初始状态 //返回状态,以便于状态的设置 public State getHappyState() { return happyState; } public State getAngryState() { return angryState; } public State getSadState() { return sadState; } public void setState(State state) { this.state = state; //在条件变化时,设置状态 } //下面三个方法将调用状态自己的方法 public void listen() { state.listen(); } public void doHomeWork() { state.doHomeWork(); } public void study() { state.study(); } }
import java.util.Scanner; //状态接口,所有状态类均需实现此接口 public interface State { public void listen(); public void doHomeWork(); public void study(); } //三个实现类 class HappyState implements State{ private Person p; //需要将Person对象传入,以便于改变状态 public HappyState(Person p) { this.p = p; } @Override public void listen() { System.out.println("I don't know the lesson"); System.out.println("Do you want to listen again"); Scanner sc=new Scanner(System.in); String str=sc.nextLine(); if(sc.equals("no")) p.setState(p.getSadState()); //通过客户的选择动态的改变状态 } @Override public void doHomeWork() { System.out.println("I don't know how to do it."); System.out.println("review?"); Scanner sc=new Scanner(System.in); String str=sc.nextLine(); if(str.equals("no")) { p.setState(p.getAngryState()); } } @Override public void study() { System.out.println("Studying Happy"); } } class AngryState implements State{ private Person p; public AngryState(Person p) { this.p = p; } @Override public void listen() { System.out.println("I can't listen more!"); } @Override public void doHomeWork() { System.out.println("It is too Hard!!!"); } @Override public void study() { System.out.println("Just want to sleep!!"); } } class SadState implements State{ private Person p; public SadState(Person p) { this.p = p; } @Override public void listen() { System.out.println("why I can't understand it!"); } @Override public void doHomeWork() { System.out.println("I can't do the homework,"); System.out.println("Just listen again?"); Scanner sc=new Scanner(System.in); String str=sc.nextLine(); if(str.equals("yes")) { p.setState(p.getHappyState()); p.listen(); } else p.setState(p.getAngryState()); } @Override public void study() { System.out.println("I can't study!"); } }
public class Test { public static void main(String[] args) { Person p=new Person(); /*客户调用Context的方法,而不知道其内部具体的状态实现*/ p.listen(); p.doHomeWork(); p.study(); } }
UML类图如下: