zoukankan      html  css  js  c++  java
  • 004-行为型-08-状态模式(State)

    一、概述

      允许一个对象在其内部状态改变时,改变它的行为

      在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。

      注意事项:在行为受状态约束的时候使用状态模式,而且状态不超过 5 个。

    1.1、适用场景

      一个对象存在多个状态(不同状态下行为不同),且状态可相互转换.

      比如:电商订单状态扭转等

      状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转译到表现不同状态的一系列类当中,可以把复杂的判断逻辑简化。  

      简单来说:

      1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
      2.一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态。
     
      1、行为随状态改变而改变的场景。
      2、条件、分支语句的代替者。

    1.2、优缺点

      优点: 1、封装了转换规则。 2、枚举可能的状态,在枚举状态之前需要确定状态种类。 3、将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。 4、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。 5、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

      缺点: 1、状态模式的使用必然会增加系统类和对象的个数。 2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。 3、状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。

    1.3、类图角色及其职责

      

      Context:它就是那个含有状态的对象,它可以处理一些请求,这些请求最终产生的响应会与状态相关。

      State:状态接口,它定义了每一个状态的行为集合,这些行为会在Context中得以使用。

      ConcreteState:具体状态,实现相关行为的具体状态类。

    1.4、演进过程

    创建一个接口

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

    创建 Context 类

    public class Context {
        private State state;
    
        public Context(){
            state = null;
        }
    
        public void setState(State state){
            this.state = state;
        }
    
        public State getState(){
            return state;
        }
    }

    创建实现接口的实体类。

    public class LogInState implements State {
        @Override
        public void doAction (Context context){
            System.out.println("登陆成功");
        }
    }
    public class LogOutState implements State {
        @Override
        public void doAction (Context context){
            System.out.println("退出成功");
        }
    }

    测试

    使用 Context 来查看当状态 State 改变时的行为变化。

        @Test
        public void test() {
            Context context = new Context();
    
            LogInState startState = new LogInState();
            startState.doAction(context);
    
    
            LogOutState stopState = new LogOutState();
            stopState.doAction(context);
    
        }

    输出

    登陆成功
    退出成功

    二、扩展

    javax.faces.lifecycle.Lifecycle、javax.faces.webapp.FacesServlet

  • 相关阅读:
    面试只要问到分布式,必问分布式锁
    Java编程中忽略这些细节,Bug肯定找上你
    不止承上启下,带你了解工业物联网关
    论文解读二十七:文本行识别模型的再思考
    并发高?可能是编译优化引发有序性问题
    论文解读丨LayoutLM: 面向文档理解的文本与版面预训练
    SQL优化老出错,那是你没弄明白MySQL解释计划
    SQL反模式学习笔记1 开篇
    SQL Server中自定义函数:用指定的分隔符号分割字符串
    .NET软件开发与常用工具清单
  • 原文地址:https://www.cnblogs.com/bjlhx/p/11576680.html
Copyright © 2011-2022 走看看