Android设计模式--状态模式

真知即所以为行,不行不足谓之知

一,定义

当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。

这么说可能很难理解,通俗来讲就是当一个对象它有多种状态的时候,把每一种状态的行为都包装在一个状态对象里,让一个对象在其内部状态改变的时候,其行为也随之改变。

状态模式将每一个条件分支放入一个独立的类中,这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化,这样通过多态来去除过多的,重复的if-else等分支语句。

二,使用场景

1,一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为。

2,代码中包含大量与对象状态有关的条件语句。

三,使用案例

假设我们的app有一种特殊场景,有离线模式和在线模式,离线模式下会进行一系列的操作,比如加载缓存等,在线模式下会进行一系列的操作,比如请求网络等。

假如我们不使用状态模式,通常代码是下面这样的:

java 复制代码
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("----加载缓存页面");
        }
    }
}

使用时:

java 复制代码
//---------------连网-----------
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判断,逻辑看起来比较混乱。

接下来我们使用状态模式看看。

首先新建一个网络状态接口:

java 复制代码
public interface NetState {

    /**
     * 处理逻辑
     * */
    void dowork();

    /**
     * 获取当前网络状态
     * */
    boolean getNetState();
}

然后创建具体的网络状态类,实现网络状态接口:

java 复制代码
public class OnLineState implements NetState{
    @Override
    public void dowork() {
        System.out.println("----请求服务器");
        System.out.println("----加载网络页面");
    }

    @Override
    public boolean getNetState() {
        return true;
    }
}
java 复制代码
public class OffLineState implements NetState{

    @Override
    public void dowork() {
        System.out.println("----读取本地缓存");
        System.out.println("----加载缓存页面");
    }

    @Override
    public boolean getNetState() {
        return false;
    }
}

然后实现单例模式的网络状态上下文类,要注意不要持有Activity引用,避免内存泄漏问题:

java 复制代码
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();
    }
}

具体使用:

java 复制代码
//-------在线----
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源码设计模式与解析第二版

相关推荐
晚安code16 小时前
设计模式入门:吃透 SOLID 原则与迪米特法则,再学 5 个高频模式
后端·设计模式
染指111020 小时前
135.Agent-多Agent框架-LangChain多智能体(SubAgents子代理)
数据库·人工智能·设计模式·langchain·agent·agents
lank_M2 天前
抠图换深色背景有白边?先分清直通和预乘alpha
图像处理·人工智能·计算机视觉·状态模式
弹简特2 天前
【Java项目-企悦抽】17-抽奖模块02-抽奖接口实现
java·开发语言·状态模式·springboot
路弥行至2 天前
【Head First 设计模式】第 2 章:观察者模式 —— 用现代 C++ 重新解读“交互对象的松耦合
c++·经验分享·笔记·观察者模式·设计模式·入门教程·headfirst
YYYing.2 天前
【设计模式系列 (九) 】装饰器模式
c++·后端·设计模式·装饰器模式·c/c++
我是你的开心果7782 天前
ai全栈软件开发学习day27
人工智能·学习·状态模式
沫璃染墨2 天前
《从零入门Linux系统篇(五十六):线程篇·九——生产者消费者模型:从条件变量到BlockingQueue实现》
linux·服务器·c++·驱动开发·设计模式·架构·系统架构
弹简特3 天前
【Java项目-企悦抽】16-抽奖模块01-获取活动完整信息接口实现
java·开发语言·状态模式·springboot
c萱3 天前
AI产品经理——01基础认知篇
设计模式·prompt·aigc·产品经理·ai编程·gitcode·ai-native