zoukankan      html  css  js  c++  java
  • 设计模式——状态模式详解

    0. 前言

    写在最前面,本人的设计模式类博文,建议先看博文前半部分的理论介绍,再看后半部分的实例分析,最后再返回来复习一遍理论介绍,这时候你就会发现我在重点处标红的用心,对于帮助你理解设计模式有奇效哦~

    此篇总结整理设计模式中的状态模式

     

    1.  状态模式介绍

    状态模式定义:

    允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。状态模式是一种对象行为型模式。

     

    状态模式的使用场景:

    1)对象的行为依赖于它的状态,并且可以在运行时根据状态改变行为

    2)代码中包含大量与对象状态有关的if/else语句,这些条件对应于对象的各种状态,这些冗余条件语句的出现导致代码的可维护性和灵活性变差,这种情况适合使用状态模式进行优化。

     

    状态模式角色介绍:


    1Context,定义客户端所感兴趣的接口,并且内部维护一个具体状态类的实例,从而维护了对象的现有状态。

    2State抽象状态类或状态接口,用以抽象封装行为。

    3ConcreteState:具体状态类,实现了State中的抽象方法。

     

    实例介绍

    在本例中,我们使用一个常见的场景,比如我们用手机打开了CSDN,找到了一篇文章,觉得写的不错,当我们点击“收藏”时,会突然跳出一个登录界面,这时我们才发觉原来我们还没有登录,如果我们已经登录成功,在点击“收藏”,就会有相应的业务逻辑处理。

     

    2.1传统的实现方案

    对于上述案例,我们很容易想到在用户点击“收藏”时,通过if/else判断用户的登录状态,从而实现不同的逻辑,伪代码如下:

    if(已经登录){
       //收藏逻辑
    }else{
       //登录逻辑
    }
    

    上述解决方案缺点非常明显:这类代码难以应对变化,在添加一种状态时,我们需要手动添加if/else,在添加一种功能时,要对所有的状态进行判断。因此代码会变得越来越臃肿,并且一旦没有处理某个状态,便会发生极其严重的BUG难以维护

     

    使用状态模式解决问题

    3.1  State接口类

    public interface State{
        public void collect (Context context);
    }
    


    3.2  State接口实现类

    public class LogInState implements State {
        @override
        public void collect (Context context){
        Toast.makeText(context,"收藏成功",Toast.LENGTH_LONG).show();
        }
    }
    
    public class LogOutState implements State {
        @override
        public void collect (Context context){
          context.startActivity(new Intent(context,LogInActivity.class));
        }
    }
    

    3.3  Context

    public class LogInContext{
    State mState = new LogOutState();//初始化为未登录状态
    static LogInContext mLogInContext = new LogInContext();
    private LogInContext(){}
    //使用单例模式提供管理类实例
    public static LogInContext getLogInContextInstance(){
        return mLogInContext;
    }
    public void collect (Context context){
    mState.collect(context);
    }
    public void setState (State state){
    this.mState = state;
    }
    }
    


    3.4  使用时

    //用户在MainActivity点击收藏按钮
    LogInContext.getLogInContextInstance.collect(MainActivity.this);
    //注销账户
    LogInContext.getLogInContextInstance.setState(new LogOutState());
    
    //登录界面LogInActivity
    if(登录验证成功){
        LogInContext.getLogInContextInstance.setState(new LogInState());
        finish();
    }
    

    状态模式的优缺点

    状态模式的优点:

    在不同状态需要有不同响应的使用场景下,避免了使用if/else导致代码臃肿,使代码结构清晰的同时保证了拓展性和维护性

     

    状态模式的缺点:

    状态模式的使用必然会增加类和对象的个数,如果使用不当将导致程序结构和代码的混乱。 

    策略模式和状态模式比较

    策略模式和状态模式的结构几乎完全一致,但是它们的目的和本质完全不一样。

    策略模式是围绕可以互换的算法来创建成功业务的,然而状态模式是通过改变对象内部的状态来帮助对象控制自己行为的。前者行为是彼此独立、可以相互替换的,后者行为是不可以相互替换的。


    至此关于状态模式的介绍就这样吧。转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52779282

    欢迎留言交流,也请大家多点下面的“顶”支持~


  • 相关阅读:
    spark 源码分析之五--Spark RPC剖析之创建NettyRpcEnv
    spark 源码分析之四 -- TaskScheduler的创建和启动过程
    spark 源码分析之三 -- LiveListenerBus介绍
    spark 源码分析之二 -- SparkContext 的初始化过程
    scala class中孤立代码块揭秘
    spark 源码分析之一 -- RDD的四种依赖关系
    spark streaming 接收kafka消息之五 -- spark streaming 和 kafka 的对接总结
    spark streaming 接收kafka消息之四 -- 运行在 worker 上的 receiver
    spark streaming 接收kafka消息之三 -- kafka broker 如何处理 fetch 请求
    spark streaming 接收kafka消息之二 -- 运行在driver端的receiver
  • 原文地址:https://www.cnblogs.com/qitian1/p/6461489.html
Copyright © 2011-2022 走看看