• Android 设计模式--状态模式


    1.状态模式

    状态模式是一种行为型设计模式。在状态模式中,类的行为是基于它的状态改变,不同状态下有不同的行为。

    状态模式把对象的行为包装在不同的状态对象里,所有的状态对象都有一个共同的抽象状态基类。状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。

     

    UML类图:

    76e3780d8ed644f9925e36be115a92d3.png

    ①状态上下文StateContext:定义用户感兴趣的接口,并保留一个具体状态子类的实例,这个具体状态类的实例给出了此环境对象的当前状态。

    ②抽象状态类/状态接口State:定义一个或一组接口来封装与Context的一个特定状态相关的行为。也就是在这里定义各种行为方法。

    ③具体状态类ConcreteState:每一个具体状态类都实现抽象状态类中定义的接口,从而达到不同状态下有不同的行为。具体状态类主要有两个职责,一是处理本状态下的事情,二是从本状态如何过渡到其他状态。

    ④客户端client:维护和管理StateContext。

     

    适用场景:

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

    ②一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态。

     

    状态模式的优点:

    ①将繁琐的状态判断转换成结构清晰的状态类族,在避免代码膨胀的同时也保证了可扩展性和可维护性。

    ②体现了开闭原则和单一职责原则,每个状态都是一个子类,要增加状态只需增加子类,要修改状态只需修改一个子类即可。

    ③符合迪米特法则。

    缺点:会增加系统类和对象的个数。

     

    2.举例

    比如一个app,它的状态有已登录和未登录两种。点击转发和评论按钮时,如果是已登录状态则可以跳转到转发、评论等页面,如果是未登录状态则跳转到登录界面。也就是说app的内部状态决定了转发和评论按钮的行为。

    ①抽象状态类:定义状态接口,里面是各种操作行为

    public interface UserState {

        public void forward(Context context);//转发

        public void comment(Context context);//评论

    }

    ②具体的状态类:已登陆状态

    public class LoginState implements UserState {

        @Override

        public void forward(Context context) {

          Toast.makeText(context, "跳转到转发页", Toast.LENGTH_LONG).show();

        }

        @Override

        public void comment(Context context) {

            Toast.makeText(context, "跳转到评论页", Toast.LENGTH_LONG).show();

        }

    }

    ③具体的状态类:未登陆状态

    public class LogoutState implements UserState {

        @Override

        public void forward(Context context) {

            gotoLoginActivity(context);

        }

        @Override

        public void comment(Context context) {

            gotoLoginActivity(context);

        }

        private void gotoLoginActivity(Context context) {

            Intent intent = new Intent(context, LoginActivity.class);

            context.startActivity(intent);

        }

    }

    ④状态上下文:实现控制

    public class LoginContext {

        UserState userState = new LogoutState();//用户状态,默认为未登录状态

        public void setUserState(UserState userState){

            this.userState = userState;

         }

        public void gotoForward(Context context) {

            userState.forward(context);

        }

       public void gotoComment(Context context){

            userState.comment(context);

        }    

    }

    状态上下文包含一个当前状态UserState的引用,并提供了一个设置状态的方法setUserState,该类还包含两个方法分别返回当前状态的行为。

    ⑤客户端

    LoginContext loginContext = new LoginContext();

    loginContext.setUserState(new LoginState);//设置为已登录状态

    loginContext.forward();//跳到转发页面

    loginContext.comment();//跳到评论页面

    loginContext.setUserState(new LogoutState());//设置为未登录状态

    loginContext.forward();//跳到登录页面

    loginContext.comment();//跳到登录页面

    首先抽象了一个UserState接口,该接口中有用户可操作的所有行为。它有两个实现类,即已登录状态和未登录状态,已登录状态下点击转发和评论按钮可跳转到对应页面,未登录状态下都跳到登录页面。app的内部状态影响了按钮的跳转行为。

    状态模式将这些行为封装到状态类中,在进行操作时将这些功能转发给状态对象,不同的状态有不同的实现,这样就通过多态的形式去除了重复的if-else语句,这也正是状态模式的精髓所在。

     

    3.状态模式和策略模式

    状态模式和策略模式的结构几乎一样,但它们的目的、本质却完全不同。状态模式的行为是平行的、不可替换的,但策略模式的行为是彼此独立、可相互替换的。

    状态模式的关键点在于不同的状态下对于同一行为有不同的响应,这其实就是一个将if-else用多态来实现的一个具体实例。在if-else或switc-case形势下根据不同的状态进行判断,如果是A那么执行方法A,状态B执行方法B,但这种实现使得逻辑耦合在一起,易于出错,通过状态模式能够很好地消除这类“丑陋”的逻辑处理。

  • 相关阅读:
    KNN和K-means算法复习
    ApplicationContext注入Bean(多线程中注入Bean)
    升学找学校小程序开发制作功能介绍
    builder(建造者模式)
    dgl的cuda版本安装+对应torch的cuda版本安装
    Nuxt3.0中使用EChart可视化图表📊
    链式二叉树(1)
    SpringBoot-logback不同业务模块输出不同的日志文件
    深度学习Course5第三周Sequence Models & Attention Mechanism习题整理
    如何优♂雅地学习GDB调试
  • 原文地址:https://blog.csdn.net/zenmela2011/article/details/126508765