设计模式-状态模式

发布于 2023-05-09 21:44:23 字数 3423 浏览 55 评论 0

现实生活中,操作某一固定事物,可能会触发不同状态,例如电灯的开关。代码中也用相类似的情况,调用某对象的同一方法或多个方法,会触发对象内部的某个状态,而这个状态会影响你下一步可能调用的方法。我们这一次就讲讲状态模式。


举例

我们的上下文 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

旧时浪漫

暂无简介

文章
评论
28 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文