设计模式-状态模式
现实生活中,操作某一固定事物,可能会触发不同状态,例如电灯的开关。代码中也用相类似的情况,调用某对象的同一方法或多个方法,会触发对象内部的某个状态,而这个状态会影响你下一步可能调用的方法。我们这一次就讲讲状态模式。
举例
我们的上下文 Light
类有 click()
方法,可以通过该方法改变电灯的状态 State
类,分别由 On
类、Off
类两种状态。
class Light {
private State state;
//
public Light(State state) {
this.state = state;
}
//通常客户端代码并不会对此方法感兴趣,这只是为了触发下面click方法时,能随即改变状态
public void setState(State state) {
this.state = state;
}
//客户端代码感兴趣的方法
public void switchLight() {
state.printAndChange(this);
}
//还可能有更复杂的形式
//public void click1() {state.printAndChange1(this);}
//上下文提供多个方法调用,同时也多可更多对状态间的变换。下面再举个例子
}
interface State {
void printAndChange(Light context);
}
class On implements State {
@Override
public void printAndChange(Light context) {
System.out.println("灯关了!");
//改变与之相反的状态
context.setState(new Off());
}
}
class Off implements State {
@Override
public void printAndChange(Light context) {
System.out.println("灯开着呢!");
//同上
context.setState(new On());
}
}
public class StatePattern {
public static void main(String[] args) {
Light light = new Light(new Off());
light.switchLight();
light.switchLight();
light.switchLight();
}
}
我们再来个稍微复杂一点的例子,假如电灯有两档亮度,那又如何?
class Light {
private State state;
public Light(State state) {
this.state = state;
}
public void setState(State state) {
this.state = state;
}
public State getState() {
return this.state;
}
//下一档
public void shiftNextGear() {
state.forward(this);
}
//上一档
public void shiftPrevGrear() {
state.reverse(this);
}
}
interface State {
void reverse(Light context);
void forward(Light context);
}
class Off implements State {
@Override
public void reverse(Light context) {
//判断是否已经关闭,若是则无法拨打上一档
if(context.getState() instanceof Off) {
throw new RuntimeException();
}
}
@Override
public void forward(Light context) {
System.out.println("电灯一档亮度!");
context.setState(new FirGear());
}
}
class FirGear implements State {
@Override
public void reverse(Light context) {
System.out.println("电灯关了!");
context.setState(new Off());
}
@Override
public void forward(Light context) {
System.out.println("电灯二档亮度!");
context.setState(new SecGear());
}
}
class SecGear implements State {
@Override
public void reverse(Light context) {
System.out.println("电灯一档亮度!");
context.setState(new FirGear());
}
@Override
public void forward(Light context) {
//判断是否已经最高档,若是则无法拨打下一档
if(context.getState() instanceof SecGear) {
throw new RuntimeException();
}
}
}
public class StatePattern {
public static void main(String[] args) {
Light light = new Light(new Off());
light.shiftNextGear();
light.shiftNextGear();
light.shiftPrevGrear();
light.shiftPrevGrear();
light.shiftPrevGrear();
}
}
最后打印出来的结果如下:
电灯一档亮度!
电灯二档亮度!
电灯一档亮度!
电灯关了!
Exception in thread "main" java.lang.RuntimeException
at Off.reverse(StatePattern.java:41)
at Light.shiftPrevGrear(StatePattern.java:28)
at StatePattern.main(StatePattern.java:9)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

上一篇: 设计模式-策略模式
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论