Android中的设计模式之状态模式
参考
- 《设计模式:可复用面向对象软件的基础 》5.8 State 状态 对象行为型模式
- 《Android源码设计模式解析与实战》第7章 随遇而安--状态模式
意图
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
别名
状态对象(Objects for States)
适用场景
- 一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
- 一个操作中含有庞大的多分支的条件语句,且这些操作分支包含这一相同的状态。这个状态通常用一个或多个枚举常量表示。
状态模式将每一个条件分支放入到一个独立的类中,这使得你可以根据对象自身的情况将对象状态作为一个对象,这一对象可以不依赖于其它对象而独立变化,这样可以通过多态来去除多的,重复的if-else等分支语句。
结构
- Context 环境类,定义客户需要的接口,维护一个State子类的实例,这个实例定义了当前环境的状态。
- State 抽象状态类或者状态接口,定义一个或者一组接口,便是该状态下的行为。
- ConcreteStateA,ConcreteStateB 具体状态类,每一个具体的状态类实现抽象State中定义的接口,从而达到不同状态下的不同行为。
优点
State模式将所有与一个特定的状态相关的行为都放入一个状态对象中,它提供了一个更好的方法来组织与特定状态相关的代码,将繁琐的状态判断转换为结构清晰的状态类族,再避免代码膨胀的同时也保证了可扩展性与可维护性。
缺点
增加了系统类和对象的个数。
应用例子1 电视遥控器
描述
电视的状态分为开机和关机状态,开机可以进行频道切换,调整音量等操作,但是这时重复开机键是无效的;关机状态下,频道切换,调整音量,关机都是无效的操作,只有按开机键会生效。
结构
代码实现
/**
* 电视不同状态下的相同抽象行为接口
* @author newtrekWang
* @email wangjiaxing20160101@gmail.com
* @time 2018/8/15 23:30
*/
public interface TvState {
/**
* 音量调高
*/
void turnOn();
/**
* 音量调低
*/
void turnOff();
/**
* 下一个频道
*/
void nextChannel();
/**
* 上一个频道
*/
void preChannel();
}
/**
* 关机状态下的行为实现
* @author newtrekWang
* @email wangjiaxing20160101@gmail.com
* @time 2018/8/15 23:22
*/
public class PowerOffState implements TvState {
@Override
public void turnOn() {
// 没有实现即失灵
}
@Override
public void turnOff() {
// 没有实现即失灵
}
@Override
public void nextChannel() {
// 没有实现即失灵
}
@Override
public void preChannel() {
// 没有实现即失灵
}
}
/**
* 开机状态下的行为实现
* @author newtrekWang
* @email wangjiaxing20160101@gmail.com
* @time 2018/8/15 23:22
*/
public class PowerOnState implements TvState {
@Override
public void turnOn() {
System.out.println("音量调高");
}
@Override
public void turnOff() {
System.out.println("音量调低");
}
@Override
public void nextChannel() {
System.out.println("切换到了下一个频道");
}
@Override
public void preChannel() {
System.out.println("切换到了上一个频道");
}
}
/**
* 电视机遥控器类
* @author newtrekWang
* @email wangjiaxing20160101@gmail.com
* @time 2018/8/15 23:29
*/
public class TvController {
private TvState state;
public void powerOn(){
this.state = new PowerOnState();
System.out.println("已开机");
}
public void powerOff(){
this.state = new PowerOffState();
System.out.println("已关机");
}
public void turnOn() {
state.turnOn();
}
public void turnOff() {
state.turnOff();
}
public void nextChannel() {
state.nextChannel();
}
public void preChannel() {
state.preChannel();
}
}
应用例子2 Android源码中的WifiDriverState
后更
应用例子3 App中的不同登陆状态下的执行行为
比如应用在已登录状态,点击评论,会正常弹出评论框,而未登录状态下,则是要跳转到登录界面登录后,再正常评论。
所以已登录和未登录状态下的评论行为是不同的,这个就可以用状态模式设计。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
Android标题栏随着滑动显示隐藏
这次实现标题栏随着上滑下滑显示隐藏 实现这个效果需要,Support Design库中的CoordinatorLayout和AppBarLayout进行配合才行。 dependencies { ... implementation 'com.android.support:design:27.1.1' //必须添加 implementation 'com.android.support:cardview-v7:27.1.1' implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.22' } xml布局代码 <?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-...
-
下一篇
Android插件化——谈谈我理解的坑位
坑位的概念 第一次听说坑位的概念是在360开源插件化框架RePlugin,我印象最深刻的就是在演讲过程中提到的只Hook了一处以及独创坑位概念。虽然下载了源码并且也大致了解了原理,但是自己好像还是有些模糊,感觉抓不到重点。昨天在看Hook AMS来实现启动一个不在AndroidManifest注册的Activity,因为版本问题,网上代码基本上都不行了。突然想起这个坑位法,决定自己尝试一次! 原理 坑位的概念是指在AndroidManifest中注册,但并没有真实的实现类,只作为其他Activity启动的坑位 Hook点为ClassLoader,Android中的ClassLoader有两个,分别为DexClassLoader和PathClassLoader,用于加载APK的是PathClassLoader,也是Android里面默认的类加载器,这个也就是需要Hook的地方。 过程如下: 启动流程 这个原理是真心简单,这里需要有关于ClassLoader和Activity启动流程的知识。 我们知道在启动一个新的Activity时,AMS会对其进行很多检测,例如是否在AndroidMan...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2全家桶,快速入门学习开发网站教程
- Dcoker安装(在线仓库),最新的服务器搭配容器使用
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- MySQL8.0.19开启GTID主从同步CentOS8
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- MySQL数据库在高并发下的优化方案
- Docker安装Oracle12C,快速搭建Oracle学习环境
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作