当前位置: 首页 > news >正文

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 &#xff0c;产生rtl的工具 hls是按照rtl code来运行的 &#xff0c; 但是rtl会在不同器件调用不同的源语&#xff1b; 可能产生的ip使用在vivado另外一个器件的话 会存在问题&#xff1b; Hls &#xff1a; vivado ip &#xff0c; vitis kernel 是…...

C#特性(Attribute)

C#特性&#xff08;Attribute&#xff09;是一种在程序中添加元数据的机制&#xff0c;它可以为代码提供额外的信息和指示。通过使用特性&#xff0c;我们可以为类、方法、属性等元素添加标记&#xff0c;以便在运行时进行更多的操作和决策。 C#特性是一种声明式编程的工具&…...

【设计模式】七大设计原则

七大设计原则 文章目录 七大设计原则一、概述二、单一职责原则三、接口隔离原则四、依赖倒转原则五、里氏替换原则六、开闭原则七、迪米特法则八、合成复用原则 一、概述 设计模式是为了让程序(软件)&#xff0c;具有更好代码重用性&#xff0c;可读性&#xff0c;可扩展性&am…...

思维导图软件 Xmind mac中文版特点介绍

XMind 2022 mac是一款思维导图软件&#xff0c;可以帮助用户创建各种类型的思维导图和概念图。 XMind mac软件特点 - 多样化的导图类型&#xff1a;XMind提供了多种类型的导图&#xff0c;如鱼骨图、树形图、机构图等&#xff0c;可以满足不同用户的需求。 - 强大的功能和工具&…...

Day32力扣打卡

打卡记录 买卖股票的最佳时机 IV&#xff08;状态机DP&#xff09; 链接 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病毒威胁,保卫您的数据

导言&#xff1a; .Elbie勒索病毒如今成为网络世界中的一大威胁&#xff0c;其狡猾性让用户防不胜防。本文将深入介绍.Elbie病毒的特点、对数据的威胁&#xff0c;提供被感染文件的恢复方法&#xff0c;并详述一系列强化网络安全的预防措施&#xff0c;让您远离.Elbie勒索病毒…...

Vue3 函数式弹窗

运行环境 vue3vitetselement-plus 开发与测试 1. 使用h、render函数创建Dialog 建议可在plugins目录下创建dialog文件夹&#xff0c;创建index.ts文件&#xff0c;代码如下 import { h, render } from "vue";/*** 函数式弹窗* param component 组件* param opti…...

如何解决 Critical dependency: the request of a dependency is an expression ?

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; ruoyi-nbcio: nbcio-boot的若依版本,基于ruoyi-flowable-plus和flowable6.7.2&#xff0c;目前处于开发功能完善阶段&#xff0c;目标是打造一个最好的若依平台上flowable流程管理系统开源版本&…...

挑战视觉边界,探索图形验证码背后的黑科技

在日常生活中&#xff0c;我们登录网站或者其他平台时&#xff0c;在填写完账号密码之后&#xff0c;还会让我们填写4或6位的数字或者英文字母等&#xff0c;填写正确才能请求登录。这个其实是防止某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试&#xff0c;如下…...

【网络奇缘】- 计算机网络|网络类型|性能指标

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏: 一见倾心,再见倾城 --- 计算机网络~&#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 计算机网络分类 1.根据范围分类 ​编辑 2.按使用者分​编辑 3.按交换技术分 ​编辑4.按拓扑结构分 ​…...

Leetcode—剑指Offer LCR 140.训练计划II【简单】

2023每日刷题&#xff08;三十三&#xff09; 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

今天&#xff0c;我们来谈谈一款在Adobe系列中推出的一款Adobe Dreamweaver&#xff0c;简称“DW”&#xff0c;中文名称 “梦想编织者”&#xff0c;是集网页制作和管理网站于一身的所见即所得网页代码编辑器。 利用对 HTML、CSS、JavaScript等内容的支持&#xff0c;设计人员…...

springMVC学习笔记-请求映射,参数绑定,响应,restful,响应状态码,springMVC拦截器

目录 概述 springMVC做了什么 springMVC与struts2区别 springMVC整个流程是一个单向闭环 springMVC具体的处理流程 springMVC的组成部分 请求映射 RequestMapping 用法 属性 1.value 2.method GET方式和POST方式 概述 HTTP给GET和POST做了哪些规定 GET方式&…...

Python实现视频字幕时间轴格式转换

自己喜欢收藏电影&#xff0c;有时网上能找到的中文字幕文件都不满足自己电影版本。在自己下载的压制版电影中已内封非中文srt字幕时&#xff0c;可以选择自己将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

默认情况下&#xff1a;每个客户端连接都会在服务器进程中拥有一个线程。 每个线程相当于一个LOCALNO的oracle远程链接。 1 该连接的查询只会在这个单独的线程中执行&#xff0c;该线程驻留在一个内核或者CPU上&#xff0c;服务器维护一个 缓冲区&#xff0c;用于存放已就绪的线…...

基于秃鹰算法优化概率神经网络PNN的分类预测 - 附代码

基于秃鹰算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于秃鹰算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于秃鹰优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络的光滑…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...