大话设计模式读书笔记(十三) 状态模式
状态模式:
状态模式定义:
状态模式(State):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像改变了其子类。
状态模式UMl类图:
状态模式Java代码实现
public class Context { //定义一个状态,并且设置该状态可以读写 private State state; public State getState() { return state; } public void setState(State state) { this.state = state; } //处理请求,并设置下一个状态 public void getResult(){ state.handle(this); } }
public interface State {
//定义一个状态接口,并抽象处理请求和设置下一状态方法
void handle(Context context);
}
public class ConcreteStateA implements State{
@Override
public void handle(Context context) {
//设置下一个状态ConcreteStateB
context.setState(new ConcreteStateB());
}
}
public class ConcreteStateB implements State{
@Override
public void handle(Context context) {
//设置下一个状态为ConcreteStateA
context.setState(new ConcreteStateA());
}
}
状态模式例子:
现在很多人家里的灯都有两个开关,床头开关和进门开关。两个开关都是双向开关,如果等是开着的,则按下开关后等就会熄灭,如果等是关着的,按下开关,等就会打开。下面是开关控制等开关的具体实现。
//灯类,拥有一个开关状态,并且由一个changer开关控制 public class Light { private Changer changer; private String state; public Light(Changer changer, String state) { super(); this.changer = changer; this.state = state; } public Changer getChanger() { return changer; } public void setChanger(Changer changer) { this.changer = changer; } public String getState() { return state; } public void setState(String state) { this.state = state; } public void changeLight(){ changer.changeState(this); } }
public interface Changer { //开关接口,定义开关灯的方法 public void changeState(Light light); } public class ChangerOn implements Changer{ //开关类具体实现,如果开着,则关闭,否则由关闭开关去实现 @Override public void changeState(Light light) { if("on".equals(light.getState())){ System.out.println("灯正在开着,现在关灯"); light.setState("Off"); light.setChanger(new ChangerOff()); }else{ light.setChanger(new ChangerOff()); light.changeLight(); } } } public class ChangerOff implements Changer { //关闭开关类具体实现,如果关着,则打开,否则由关闭开关去实现 @Override public void changeState(Light light) { if("off".equals(light.getState())){ System.out.println("灯正在关着,现在开灯"); light.setState("on"); light.setChanger(new ChangerOn()); }else{ light.setChanger(new ChangerOn()); light.changeLight(); } } }
主方法:
public class Main { public static void main(String[] args) { Changer changer =new ChangerOn(); //初始状态,灯开着 Light light = new Light(changer, "on"); //Light light = new Light(changer, "off"); light.changeLight(); } }
------------------------------------------------分割线--------------------------------------------
状态模式和策略模式的区别:
在网上查了一些资料,感觉知乎上一个名为胖胖的大牛解释的非常好,虽然有点污。本想借鉴一下,但是不让转载,这里只能附上链接,大家可以自己去看一下。https://www.zhihu.com/question/23693088
区别:
状态模式将各个状态所对应的操作分离开来,即对于不同的状态,由不同的子类实现具体操作,不同状态的切换由子类实现,当发现传入参数不是自己这个状态所对应的参数,则自己给Context类切换状态;而策略模式是直接依赖注入到Context类的参数进行选择策略,不存在切换状态的操作。