十六、状态模式—用类表示状态 #和设计模式一起旅行#

人有悲欢离合,月有阴晴圆缺!故事背景白天、黑夜是不同的状态,水蒸气、冰是水不同的状态,大千的世界,不同的各种东西会有很多种状态,本篇要介绍的就是 “用类来表示状态”,用类表示状态后,我们就可以切换类来方便地改变对象的状态。故事主角状态模式:允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。在状态模式结构中包括几个角色: – Conte…

大家好,又见面了,我是全栈君。

人有悲欢离合,月有阴晴圆缺!

故事背景

白天、黑夜是不同的状态,水蒸气、冰是水不同的状态,大千的世界,不同的各种东西会有很多种状态,本篇要介绍的就是 “用类来表示状态”,用类表示状态后,我们就可以切换类来方便地改变对象的状态。

故事主角

状态模式:允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。

状态模式类图

在状态模式结构中包括几个角色:
– Context(环境类):环境类又称为上下文类,它是拥有多种状态的对象。
– State(抽象状态类):它用于定义一个接口以封装与环境类的一个特定状态相关的行为,在抽象状态类中声明了各种不同状态对应的方法,而在其子类中实现类这些方法。
– ConcreteState(具体状态类):它是抽象状态类的子类,每一个子类实现一个与环境类的一个状态相关的行为,每一个具体状态类对应环境的一个具体状态。

状态模式用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题。

状态模式和策略模式是双胞胎,在出生的时候才分开。

注意:状态转换有两种方式
1. 统一由环境类来负责状态之间的转换
2. 由具体状态类来负责状态之间的转换

武功修炼

武功修炼我们看一个电梯的例子:

一个电梯有四个动作:开门、关门、运行、停止。

门开状态:在这个状态下电梯只能做的动作是关门动作!

门闭状态:电梯门关闭了,在这个状态下,可以进行的动作是:开门(我不想坐电梯了)、停止(忘
记按路层号了)、运行!

运行状态:电梯正在跑,上下窜,在这个状态下,电梯只能做的是停止!

停止状态:电梯停止不动,在这个状态下,电梯有两个可选动作:继续运行和开门动作;

电梯运行状态图

public class Context { 
   

    //定义出所有的电梯状态
    public final static OpenningState openningState = new OpenningState();
    public final static ClosingState closeingState = new ClosingState();
    public final static RunningState runningState = new RunningState();
    public final static StoppingState stoppingState = new StoppingState();
    //定一个当前电梯状态
    private LiftState liftState;

    public LiftState getLiftState() {
        return liftState;
    }
    public void setLiftState(LiftState liftState) {
        this.liftState = liftState;
        //把当前的环境通知到各个实现类中
        this.liftState.setContext(this);
    }

    public void open(){
        this.liftState.open();
    }
    public void close(){
        this.liftState.close();
    }
    public void run(){
        this.liftState.run();
    }
    public void stop(){
        this.liftState.stop();
    }
}


public class OpenningState extends LiftState { 
   
    @Override
    public void open() {
        System.out.println("电梯门开启....");
    }

    @Override
    public void close() {
    // 电梯门开启状态,则当然可以进行关闭操作
        super.context.setLiftState(Context.closeingState);
        super.context.getLiftState().close();

    }

    @Override
    public void run() {
        //do nothind
    }

    @Override
    public void stop() {
        //do nothind
    }

}
public class ClosingState extends LiftState { 
   
    //电梯门关闭,这是关闭状态要实现的动作
    @Override
    public void close() {
        System.out.println("电梯门关闭...");
    }
    //电梯门关了再打开,逗你玩呢,那这个允许呀
    @Override
    public void open() {
        super.context.setLiftState(Context.openningState); //置为门敞状态
        super.context.getLiftState().open();
    }

    //电梯门关了就跑,这是再正常不过了
    @Override
    public void run() {
        super.context.setLiftState(Context.runningState); //设置为运行状态;
        super.context.getLiftState().run();
    }
    //电梯门关着,我就不按楼层
    @Override
    public void stop() {
        super.context.setLiftState(Context.stoppingState); //设置为停止状态;
        super.context.getLiftState().stop();
    }
}

public class RunningState extends LiftState { 
   
    //电梯门关闭?这是肯定了
    @Override
    public void close() {
    //do nothing
    }
    //运行的时候开电梯门?你疯了!电梯不会给你开的
    @Override
    public void open() {
    //do nothing
    }
    //这是在运行状态下要实现的方法
    @Override
    public void run() {
        System.out.println("电梯上下跑...");
    }
    //这个事绝对是合理的,光运行不停止还有谁敢做这个电梯?!估计只有上帝了
    @Override
    public void stop() {
        super.context.setLiftState(Context.stoppingState); //环境设置为停止状态;
        super.context.getLiftState().stop();
    }
}


public class StoppingState extends LiftState { 
   
    //停止状态关门?电梯门本来就是关着的!
    @Override
    public void close() {
        //do nothing;
    }
    //停止状态,开门,那是要的!
    @Override
    public void open() {
        super.context.setLiftState(Context.openningState);
        super.context.getLiftState().open();
    }
    //停止状态再跑起来,正常的很
    @Override
    public void run() {
        super.context.setLiftState(Context.runningState);
        super.context.getLiftState().run();
    }

    //停止状态是怎么发生的呢?当然是停止方法执行了
    @Override
    public void stop() {
        System.out.println("电梯停止了...");
    }
}

public class TestClient { 
   

    public static void main(String[] args) {
        Context context = new Context();
        // 设置电梯的初始化状态为关闭
        context.setLiftState(new ClosingState());
        context.open();
        context.close();
        context.run();
        context.stop();
    }
}


电梯门开启....
电梯门关闭...
电梯上下跑...
电梯停止了...

此例子来自于-Java设计模中!
此例中使用环境类切换状态!

总结

优点:
– 封装了状态的状态的转换
– 将所有与状态相关的行为放到一个类中
– 多个环境可以共享也给状态对象

缺点:
– 状态太多的话,增加系统的类的数量,导致系统开销增大
– 使用不恰当,导致程序结构和代码混乱

适合场景:
– 对象的行为依赖它的状态,状态的改变将导致行为的变化。
– 在代码中包含大量与对象状态有关的条件语句(if-else 或者 switch 等),这些条件语句的出现,会导致代码的可维护性和灵活性变差,不能方便地增加和删除状态,并且导致客户类与类库之间的耦合增强。

Next 期待下一篇吧!下一篇讲讲责任链模式!

参考

本专栏文章列表

一、设计模式-开篇—为什么我要去旅行? #和设计模式一起旅行#
二、设计模式-必要的基础知识—旅行前的准备 #和设计模式一起旅行#
三、设计模式介绍—她是谁,我们要去哪里? #和设计模式一起旅行#
四、单例模式—不要冒充我,我只有一个! #和设计模式一起旅行#
五、工厂模式—旅行的钱怎么来 #和设计模式一起旅行#
六、策略模式—旅行的交通工具 #和设计模式一起旅行#
七、观察者模式——关注我,分享旅途最浪漫的瞬间! #和设计模式一起旅行#
八、装饰者模式—巴厘岛,奶茶店的困扰! #和设计模式一起旅行#
九、命令模式—使用命令控制奶茶店中酷炫的灯 #和设计模式一起旅行#
十、模板方法模式—制作更多好喝的饮品! #和设计模式一起旅行#
十一、代理模式 —专注,做最好的自己!#和设计模式一起旅行#
十二、适配器模式——解决充电的烦恼 #和设计模式一起旅行#
十三、外观模式—— 简化接口 #和设计模式一起旅行#
十四、迭代器模式—— 一个一个的遍历 #和设计模式一起旅行#
十五、组合模式—— 容器与内容的一致性 #和设计模式一起旅行#
十六、状态模式—用类表示状态 #和设计模式一起旅行#
十七、访问者模式-访问数据结构并处理数据 #和设计模式一起旅行#
十八、职责链模式-推卸责任,不关我的事,我不管!#和设计模式一起旅行#
十九、原型模式—通过复制生产实例 #和设计模式一起旅行#
二十、设计模式总结—后会有期 #和设计模式一起旅行#


如果您觉得这篇博文对你有帮助,请点赞或者喜欢,让更多的人看到,谢谢!

如果帅气(美丽)、睿智(聪颖),和我一样简单善良的你看到本篇博文中存在问题,请指出,我虚心接受你让我成长的批评,谢谢阅读!
祝你今天开心愉快!


欢迎访问我的csdn博客,我们一同成长!

不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/121085.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • .NET设计模式访问者模式

    一.访问者模式的定义:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。二.访问者模式的结构和角色:1.Visitor抽象访问者角色,为该

    2021年12月24日
    41
  • cglib动态代理实现原理_java设计模式之代理模式

    cglib动态代理实现原理_java设计模式之代理模式代理模式(ProxyPattern)是一种结构性模式。代理模式为一个对象提供了一个替身,以控制对这个对象的访问。即通过代理对象访问目标目标对象,可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。文章目录代理模式静态代理动态代理cglib代理应用

    2022年10月16日
    0
  • ❤️设计模式肝完了,还挺全!腾讯和阿里的offer已拿!❤️

    ❤️设计模式肝完了,还挺全!腾讯和阿里的offer已拿!❤️设计模式肝完了,还挺全!腾讯和阿里的offer已拿!金九银十已经来了,挺近大厂最好的机会已经来了!如果你是要找工作的,一定要抓住这个机会!前面已经整理了很多的面试资料:1,❤️爆肝!整理了一周的Spring面试大全【含答案】,吊打Java面试官【建议收藏】!❤️2,❤️肝完了,一天掌握数据结构和算法面试题,吊打面试官,建议收藏❤️3,❤️集合很简单?开什么玩笑?肝了一周,全是精华,万字讲解!面试再不怕集合问题了!!!❤️4,肝完了,总结了SpringBoot与缓存的知识点,快速掌

    2022年6月10日
    23
  • 极速理解设计模式系列:14.轻量级模式(Flyweight Pattern)「建议收藏」

    极速理解设计模式系列:14.轻量级模式(Flyweight Pattern)

    2022年3月8日
    39
  • 从零开始的Android:常见的UI设计模式「建议收藏」

    从零开始的Android:常见的UI设计模式「建议收藏」尽管Android允许您创建几乎任何可能需要的自定义视图或用户界面,但事实证明,在正确的情况下,有一些用户界面模式可以很好地适用于用户。在本教程中,您将学习其中的一些模式,以及它们如何通过在使用应用程序时创造出色的体验来帮助用户。1.主画面用户在打开应用程序时看到的第一个屏幕通常是最重要的。从这里开始,您的用户应该能够执行快速动作并继续前进,或者进一步深入到您的应用中以完善他们…

    2022年6月21日
    25
  • 一、设计模式-开篇—为什么我要去旅行? #和设计模式一起旅行#

    独学而无友,则孤陋而寡闻。——《礼记·学记》写在开篇,本篇是一个综合帖,里面可能会记录一些我的学习感受,也可能记录一些我学习的资料的说明,总之这就是一个大杂烩的博文。开篇杂谈最近学习一些技术之外的其他东西,怎么进行时间管理了,怎么坚持去做一件事情了,还是学到了一些其他的新的东西!做一件事情最难的是什么,是启动!启动之后最难是什么,是坚持!很多时候大的道理我们都懂,但…

    2022年2月27日
    48

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号