Android设计模式--状态模式
真知即所以为行,不行不足谓之知
一,定义
当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。
这么说可能很难理解,通俗来讲就是当一个对象它有多种状态的时候,把每一种状态的行为都包装在一个状态对象里,让一个对象在其内部状态改变的时候,其行为也随之改变。
状态模式将每一个条件分支放入一个独立的类中,这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化,这样通过多态来去除过多的,重复的if-else等分支语句。
二,使用场景
1,一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为。
2,代码中包含大量与对象状态有关的条件语句。
三,使用案例
假设我们的app有一种特殊场景,有离线模式和在线模式,离线模式下会进行一系列的操作,比如加载缓存等,在线模式下会进行一系列的操作,比如请求网络等。
假如我们不使用状态模式,通常代码是下面这样的:
public class WorkEvent {private boolean isNet;public WorkEvent(boolean isNet) {this.isNet = isNet;}public void doWork(){if(isNet){System.out.println("----请求服务器");System.out.println("----加载网络页面");}else {System.out.println("----读取本地缓存");System.out.println("----加载缓存页面");}}
}
使用时:
//---------------连网-----------
ConfigManger.getEtnConfigRepository().saveNetState(true);//存到sp里网络状态
WorkEvent workEvent =new WorkEvent(true);
workEvent.doWork();
//----------------断网---------------
ConfigManger.getEtnConfigRepository().saveNetState(false);//存到sp里网络状态
WorkEvent workEvent =new WorkEvent(false);
workEvent.doWork();
这样做,不仅需要在内存中存储网络状态,还要在处理类中增加各种if-else判断,逻辑看起来比较混乱。
接下来我们使用状态模式看看。
首先新建一个网络状态接口:
public interface NetState {/*** 处理逻辑* */void dowork();/*** 获取当前网络状态* */boolean getNetState();
}
然后创建具体的网络状态类,实现网络状态接口:
public class OnLineState implements NetState{@Overridepublic void dowork() {System.out.println("----请求服务器");System.out.println("----加载网络页面");}@Overridepublic boolean getNetState() {return true;}
}
public class OffLineState implements NetState{@Overridepublic void dowork() {System.out.println("----读取本地缓存");System.out.println("----加载缓存页面");}@Overridepublic boolean getNetState() {return false;}
}
然后实现单例模式的网络状态上下文类,要注意不要持有Activity引用,避免内存泄漏问题:
public class NetStateContext {private NetStateContext() {}// 私有的静态内部类private static class Holder {private static NetStateContext instance = new NetStateContext();}// 开放的获取单例对象的方法public static NetStateContext getInstance() {return NetStateContext.Holder.instance;}private NetState netState =new OnLineState();//默认在线public void setNetState(NetState netState) {this.netState = netState;this.netState.dowork();}public boolean getNetState(){return netState.getNetState();}
}
具体使用:
//-------在线----
NetStateContext.getInstance().setNetState(new OnLineState());
System.out.println("当前在线状态:"+NetStateContext.getInstance().getNetState());
//-------离线----
NetStateContext.getInstance().setNetState(new OffLineState());
System.out.println("当前在线状态:"+NetStateContext.getInstance().getNetState());
输出:

这样代码就看起来清晰多了,而且状态的管理也不用去开辟内存存储了。在实际开发中,状态模式的使用对我来说还是比较多的。
四,总结
状态模式的关键点在于不同的状态下对于同一行为有不同的响应,这其实就是一个将if-else替换的具体示例。当然并不是任何出现if-else的地方都应该通过状态模式重构。一定要结合实际的场景来综合评估。
优点:状态模式将所有与一个特定的状态相关的行为都放入一个状态对象中,它提供了一个更好的方法来组织与特定状态相关的代码,将繁琐的状态判断转换成结构清晰的状态类族,在避免代码膨胀的同时,也保证了可扩展性与可维护性。
缺点:状态模式的使用必然会增加类和对象的个数。
参考文献:Android源码设计模式与解析第二版
相关文章:
Android设计模式--状态模式
真知即所以为行,不行不足谓之知 一,定义 当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。 这么说可能很难理解,通俗来讲就是当一个对象它有多种状态的时候,把每一种状态的行为…...
C++关系运算符重载
#include<iostream> using namespace std;class Person { public:string name;int age;Person(string n, int a){name n;age a;}//friend bool operator(Person& p1, Person& p2); 使用友元//成员函数实现函数关系符重载bool operator(Person& p) {if (na…...
HLS基础issue
hls 是一个用C/c 来开发PL ,产生rtl的工具 hls是按照rtl code来运行的 , 但是rtl会在不同器件调用不同的源语; 可能产生的ip使用在vivado另外一个器件的话 会存在问题; Hls : vivado ip , vitis kernel 是…...
C#特性(Attribute)
C#特性(Attribute)是一种在程序中添加元数据的机制,它可以为代码提供额外的信息和指示。通过使用特性,我们可以为类、方法、属性等元素添加标记,以便在运行时进行更多的操作和决策。 C#特性是一种声明式编程的工具&…...
【设计模式】七大设计原则
七大设计原则 文章目录 七大设计原则一、概述二、单一职责原则三、接口隔离原则四、依赖倒转原则五、里氏替换原则六、开闭原则七、迪米特法则八、合成复用原则 一、概述 设计模式是为了让程序(软件),具有更好代码重用性,可读性,可扩展性&am…...
思维导图软件 Xmind mac中文版特点介绍
XMind 2022 mac是一款思维导图软件,可以帮助用户创建各种类型的思维导图和概念图。 XMind mac软件特点 - 多样化的导图类型:XMind提供了多种类型的导图,如鱼骨图、树形图、机构图等,可以满足不同用户的需求。 - 强大的功能和工具&…...
Day32力扣打卡
打卡记录 买卖股票的最佳时机 IV(状态机DP) 链接 class Solution:def maxProfit(self, k: int, prices: List[int]) -> int:n len(prices)max lambda x, y: x if x > y else yf [[-0x3f3f3f3f] * 2 for _ in range(k 2)]for i in range(k 2…...
抗击.Elbie勒索病毒:如何应对.Elbie病毒威胁,保卫您的数据
导言: .Elbie勒索病毒如今成为网络世界中的一大威胁,其狡猾性让用户防不胜防。本文将深入介绍.Elbie病毒的特点、对数据的威胁,提供被感染文件的恢复方法,并详述一系列强化网络安全的预防措施,让您远离.Elbie勒索病毒…...
Vue3 函数式弹窗
运行环境 vue3vitetselement-plus 开发与测试 1. 使用h、render函数创建Dialog 建议可在plugins目录下创建dialog文件夹,创建index.ts文件,代码如下 import { h, render } from "vue";/*** 函数式弹窗* param component 组件* param opti…...
如何解决 Critical dependency: the request of a dependency is an expression ?
更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: ruoyi-nbcio: nbcio-boot的若依版本,基于ruoyi-flowable-plus和flowable6.7.2,目前处于开发功能完善阶段,目标是打造一个最好的若依平台上flowable流程管理系统开源版本&…...
挑战视觉边界,探索图形验证码背后的黑科技
在日常生活中,我们登录网站或者其他平台时,在填写完账号密码之后,还会让我们填写4或6位的数字或者英文字母等,填写正确才能请求登录。这个其实是防止某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,如下…...
【网络奇缘】- 计算机网络|网络类型|性能指标
🌈个人主页: Aileen_0v0🔥系列专栏: 一见倾心,再见倾城 --- 计算机网络~💫个人格言:"没有罗马,那就自己创造罗马~" 目录 计算机网络分类 1.根据范围分类 编辑 2.按使用者分编辑 3.按交换技术分 编辑4.按拓扑结构分 …...
Leetcode—剑指Offer LCR 140.训练计划II【简单】
2023每日刷题(三十三) Leetcode—LCR 140.训练计划II 实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* trainingPlan(struct ListNode* head, int cnt) {str…...
梦想编织者——Adobe Dreamweaver
今天,我们来谈谈一款在Adobe系列中推出的一款Adobe Dreamweaver,简称“DW”,中文名称 “梦想编织者”,是集网页制作和管理网站于一身的所见即所得网页代码编辑器。 利用对 HTML、CSS、JavaScript等内容的支持,设计人员…...
springMVC学习笔记-请求映射,参数绑定,响应,restful,响应状态码,springMVC拦截器
目录 概述 springMVC做了什么 springMVC与struts2区别 springMVC整个流程是一个单向闭环 springMVC具体的处理流程 springMVC的组成部分 请求映射 RequestMapping 用法 属性 1.value 2.method GET方式和POST方式 概述 HTTP给GET和POST做了哪些规定 GET方式&…...
Python实现视频字幕时间轴格式转换
自己喜欢收藏电影,有时网上能找到的中文字幕文件都不满足自己电影版本。在自己下载的压制版电影中已内封非中文srt字幕时,可以选择自己将srt的时间轴转为ass并替换ass中的时间轴。自己在频繁 复制粘贴改格式的时候想起可以用Python代码完成转换这一操作&…...
蓝桥杯 枚举
例题讲解 特别数的和 #include<iostream> using namespace std; bool ifspecial(int n){while(n){if(n%100||n%101||n%102||n%109){return true;} n/10;}return false; } int main(){int n;cin>>n;int sum0;for(int i1;i<n;i){if(ifspecial(i)){sumi;}}cout&l…...
C#的MessagePack(unity)--02
高级API (MessagePackSerializer) MessagePackSerializer类是MessagePack for C# 的入口点。静态方法构成了MessagePack for C# 的主要API。 APIDescriptionSerialize<T>将一个对象图序列化为MessagePack二进制块。可以使用异步变体获取Stream。也有非泛型重载可用。De…...
MySQL数据库管理--- mysql数据库迁移-v查看报错sql
默认情况下:每个客户端连接都会在服务器进程中拥有一个线程。 每个线程相当于一个LOCALNO的oracle远程链接。 1 该连接的查询只会在这个单独的线程中执行,该线程驻留在一个内核或者CPU上,服务器维护一个 缓冲区,用于存放已就绪的线…...
基于秃鹰算法优化概率神经网络PNN的分类预测 - 附代码
基于秃鹰算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于秃鹰算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于秃鹰优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要:针对PNN神经网络的光滑…...
GLM-4.1V-9B-Base基础教程:3步完成图片上传→中文提问→结果解析
GLM-4.1V-9B-Base基础教程:3步完成图片上传→中文提问→结果解析 1. 认识GLM-4.1V-9B-Base GLM-4.1V-9B-Base是智谱开源的一款视觉多模态理解模型,专门用于处理图像内容识别、场景描述、目标问答和中文视觉理解任务。这个模型已经完成了Web化封装&…...
A3:高级文本分析能力
A3:高级文本分析能力 【免费下载链接】Neosgenesis https://dev.to/answeryt/the-demo-spell-and-production-dilemma-of-ai-agents-how-i-built-a-self-learning-agent-system-4okk 项目地址: https://gitcode.com/gh_mirrors/ne/Neosgenesis 适配问题类型&…...
保姆级教程:在STM32F103上从零移植FreeModbus V1.6(RTU模式)
保姆级教程:在STM32F103上从零移植FreeModbus V1.6(RTU模式) Modbus协议作为工业自动化领域的"普通话",其开源实现FreeModbus凭借轻量级和可移植性成为嵌入式开发者的首选。本文将手把手带你在STM32F103C8T6开发板上完成…...
3个秘诀彻底解决机械键盘连击问题:Keyboard Chatter Blocker全攻略
3个秘诀彻底解决机械键盘连击问题:Keyboard Chatter Blocker全攻略 【免费下载链接】KeyboardChatterBlocker A handy quick tool for blocking mechanical keyboard chatter. 项目地址: https://gitcode.com/gh_mirrors/ke/KeyboardChatterBlocker 机械键盘…...
智能处理与开源工具:突破传统背景抠图限制的实时解决方案
智能处理与开源工具:突破传统背景抠图限制的实时解决方案 【免费下载链接】obs-backgroundremoval An OBS plugin for removing background in portrait images (video), making it easy to replace the background when recording or streaming. 项目地址: https…...
从变砖到重生:红魔全系9008深度救砖指南与实战解析
1. 什么是9008模式?为什么能救砖? 当你发现红魔手机卡在开机界面、反复重启甚至完全黑屏时,大概率是遇到了传说中的"变砖"。这时候高通芯片隐藏的9008模式就是最后的救命稻草。简单来说,9008模式相当于电脑的BIOS界面&…...
图解Linux内核DRM框架:从用户态ioctl到plane更新的完整数据流(以4.14版本为例)
图解Linux内核DRM框架:从用户态ioctl到plane更新的完整数据流(以4.14版本为例) 在图形显示技术领域,Linux内核的DRM(Direct Rendering Manager)框架扮演着核心角色。本文将聚焦于DRM_IOCTL_MODE_SETPLANE这…...
Z-Image-Turbo LoRA WebUI实战案例:为独立游戏开发者生成角色立绘素材
Z-Image-Turbo LoRA WebUI实战案例:为独立游戏开发者生成角色立绘素材 1. 项目概述与价值 作为一名独立游戏开发者,你是否曾经为角色立绘的设计而头疼?传统的美术外包成本高昂,自己绘制又需要专业技能。现在,通过Z-I…...
网站SEO优化与网站内容更新的关系_企业网站SEO优化与行业特点的关系
<h3 id"seo_seo">网站SEO优化与网站内容更新的关系_企业网站SEO优化与行业特点的关系</h3> <p>在当今数字化时代,网站的SEO优化与内容更新之间有着密切的关系。这不仅关系到企业网站的流量,还直接影响企业的品牌形象和市场竞…...
电源管理入门-4子系统reset
之前的文章电源管理入门-1关机重启详解介绍了整机SoC的重启也可以说是reset,那么子系统的reset,例如某个驱动(网卡、USB等)或者某个子系统(NPU、ISP等运行在独立的M核或者R核上的AI系统),这些零…...
