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

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


  • 相关阅读:
    zoj 3279 线段树 OR 树状数组
    fzu 1962 树状数组 OR 线段树
    hdu 5057 块状链表
    hdu3487 Play with Chain
    bzoj 1588营业额统计(HNOI 2002)
    poj2823 Sliding Window
    poj2828 Buy Tickets
    poj2395 Out of Hay
    poj3667 Hotel
    poj1703 Lost Cows
  • 原文地址:https://www.cnblogs.com/qitian1/p/6461489.html
Copyright © 2011-2022 走看看