文档章节

设计模式之状态模式

陈年之后是青葱
 陈年之后是青葱
发布于 11/22 01:25
字数 882
阅读 20
收藏 0

定义

Allow an object to alter its behavior when its internal state changes.The object will appear to change its class.(当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。)

UML类图

角色解释

  • Context,环境,封装各种状态的变化,并且向外部提供所有需要的接口,使得外部不用关注状态的变化,只需要关注抽象的行为,以及初始状态。
  • State,状态,抽象所有状态的行为,并且依赖Context,提供setContext方法。
  • ConcreateState,状态实现,总结下就是每个状态只关注自己的行为实现,针对不属于自己的行为可以进行抛错。

代码示例

已开门状态和关门状态举例:

Context类:

public class DoorContext {
    public static final DoorState OPEN_STATE = new OpenState();
    public static final DoorState CLOSE_STATE = new CloseState();
    /**
     * 当前状态
     */
    private DoorState currentState;

    /**
     * 获得当前状态
     */
    public DoorState getCurrentState() {
        return currentState;
    }

    public void setCurrentState(DoorState doorState) {
        doorState.setDoorContext(this);
        this.currentState = doorState;
    }

    public void close() {
        this.currentState.close();
    }

    public void open() {
        this.currentState.open();
    }

    public void enter() {
        this.currentState.enter();
    }

    public void out() {
        this.currentState.out();
    }

    public void knock() {
        this.currentState.knock();
    }
}

State抽象类:

public abstract class DoorState {
    protected DoorContext doorContext;

    public void setDoorContext(DoorContext _Door_context) {
        this.doorContext = _Door_context;
    }

    public abstract void open();

    public abstract void close();

    public abstract void enter();

    public abstract void out();

    public abstract void knock();

}

关门状态实现类:

   @Override
    public void open() {
        System.out.println("开门");
        //切换状态
        super.doorContext.setCurrentState(DoorContext.OPEN_STATE);
    }


    @Override
    public void close() {
        System.out.println("已关门");
    }


    @Override
    public void knock() {
        System.out.println("关着的门用力敲");
    }


    @Override
    public void enter() {
        throw new RuntimeException("门关了,进门失败");
    }

    @Override
    public void out() {
        throw new RuntimeException("门关了,出门失败");
    }

开门状态实现类:

public class OpenState extends DoorState {
    @Override
    public void enter() {
        System.out.println("进入");
    }

    @Override
    public void out() {
        System.out.println("出来");
    }

    @Override
    public void knock() {
        System.out.println("开着的门轻轻敲");
    }

    @Override
    public void open() {
        System.out.println("门已经开着了");
    }

    /**
     * 涉及到切换到其他状态
     */
    @Override
    public void close() {
        System.out.println("关门");
        super.doorContext.setCurrentState(DoorContext.CLOSE_STATE);
    }
}

场景类1:

 public static void main(String[] args) {
        DoorContext doorContext = new DoorContext();
        //给个初始状态
        doorContext.setCurrentState(DoorContext.CLOSE_STATE);
        //敲门
        doorContext.knock();
        //开门
        doorContext.open();
        //进门
        doorContext.enter();
        //关门
        doorContext.close();
        //进门
        doorContext.open();
        //出门
        doorContext.out();
        //关门
        doorContext.close();
    }

观察场景类可以知道,当场景类调用的时候,根本不需要在意状态,只需要关注需要实现的行为,而具体能不能实现行为,具体怎么实现这个行为,状态的流转,则被封装在了Context里。

应用场景

  • 行为与状态有相互依赖的关系。 也就是说,行为受状态影响(状态会改变行为),而状态也受行为影响(行为会改变状态),状态模式就是将每个状态抽出来,然后针对每个行为进行实现,遇到切换状态的行为的时候将当前场景Context里面的状态切换就行了。而对于Context来说,只需要将外部的调用转发个当前场景内部的状态去处理就行了。

优点

  • 屏蔽了状态切换,并且又拥有良好的健壮性,没有忽视行为受状态的影响,只是封装在了状态内部去去处理了。
  • 符合单一职责,如果不应用状态模式,那么状态和行为是耦合在一个类中,不符合单一职责原则。
  • 符合开闭原则,高层模块不关注具体状态实现,如果需要扩展状态,只需要在底层添加一个状态实现类就是了。

© 著作权归作者所有

陈年之后是青葱
粉丝 6
博文 62
码字总数 73772
作品 0
九龙坡
程序员
私信 提问
JavaScript设计模式总结

之前看过《JavaScript设计模式与开发实践》这本书,对书中的设计模式和一些相关案例也有了一定的了解,同时把这些设计模式的应用对应在在一些其他的项目中,进行了一些整理,如下仅供参考: ...

jefferyE
03/26
0
0
设计模式 2014-12-19

book: 阎宏《JAVA与模式》 架构设计栏目 http://blog.csdn.net/enterprise/column.html 概要: http://bbs.csdn.net/forums/Embeddeddriver 23种设计模式分别是: 1.单例模式 2.工厂方法模式...

jayronwang
2014/12/19
308
0
Ubuntu中vi卸载与安装/使用模式

Ubuntu中安装的vi是vim-common版本,与centos系统中vi使用方式不同,编辑使用不惯, 遂卸载重装,卸载命令:sudo apt-get remove vim-common 卸载完毕后重新安装;输入命令:sudo apt-get in...

唐十三郎
2018/11/27
289
0
《PHP设计模式大全》系列分享专栏

《PHP设计模式大全》已整理成PDF文档,点击可直接下载至本地查阅 https://www.webfalse.com/read/201739.html 文章 php设计模式介绍之编程惯用法第1/3页 php设计模式介绍之值对象模式第1/5页...

kaixin_code
2018/11/06
201
0
【设计模式笔记】(十六)- 代理模式

一、简述 代理模式(Proxy Pattern),为其他对象提供一个代理,并由代理对象控制原有对象的引用;也称为委托模式。 其实代理模式无论是在日常开发还是设计模式中,基本随处可见,中介者模式中...

MrTrying
2018/06/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

把阿里巴巴的核心系统搬到云上,架构上的挑战与演进是什么?

作者丨张瓅玶(谷朴)阿里巴巴研究员 阿里巴巴核心系统作为全球最大规模、峰值性能要求最高的电商交易系统,在 2018 年之前只通过混合云弹性上云方式,为 双11 节约大量成本。直到 2019 年,...

阿里巴巴云原生
17分钟前
2
0
PHP MySQLi 系列函数

如何用mysqli系列函数连接一个mysql数据库? 1.PHP mysqli_connect()函数:mysqli_connect() 函数打开一个到 MySQL 服务器的新的连接。 语法:mysqli_connect ( host (规定主机名或IP地址), ...

imzchloe
35分钟前
2
0
如何在Notepad ++中格式化XML?

我有Notepad ++ ,我得到了一些非常长的XML代码。 当我将它粘贴在Notepad ++中时,存在很长的代码行(难以阅读和使用)。 我想知道是否有一种简单的方法可以使文本可读(通过可读,我的意思是...

技术盛宴
50分钟前
6
0
(Object[])null

dbutils下QueryRunner.java 的一段代码: package org.apache.commons.dbutils; public <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh) throws SQLException { ......

行者终成事
51分钟前
5
0
商品评价

商品评价 商品评价 商品评价:指买家对所购买商品的评价。 一、商品评价的具体操作:在个人中心找到商品评价,找到商品对其评价,添加评价内容,添加商品图片。 二、商品评价在后台的具体显示...

Geek-Chic
54分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部