用状态模式构造复杂状态的最佳方法?

问题描述

我有一个可以处于不同状态的菜单,所以我决定使用状态模式。在线阅读有关该模式的内容似乎是从另一个状态构造状态的常用方法,但这对我不起作用,因为我有更复杂的状态需要其他依赖项。我可以在上下文对象中预先创建所有状态,然后从上下文对象切换状态,但我还需要来自先前状态的一些信息,因此它也会变得混乱。

     class State1 {
         public State1(Context context,/*some complex constructor*/) {
         }
         public void Action() {
            //Something happend and we want to transition to other state
               
            //Usual way 
            //this will not work because state1 doesnt have 
            //dependencies to construct state2
            //context->SetState(new State2());
            

            //My current way
            //This is better because it works,but you will have to create
            //such functions for every state and context object needs to be 
            //modified if new states are added which is not ideal
            context->SetState2(/*something produced by action in state1*/);
         }
     }   

    class State2 {
         public State2(Context context,/*some complex constructor*/) {
         }
     }   
     
     
    class Context {
      //has current state 
    }

这是一个糟糕设计的迹象吗?
有没有一个干净的解决方案,或者我想太多了?

解决方法

OP 代码中遗漏的一个重要细节是状态设计模式中的状态是多态的(所有状态都有一个共享的 API)。

class State1 implements State {}
class State2 implements State {}
class Context { private volatile State currentState; }

在没有多态状态的情况下,没有状态设计模式。实例化状态应该以与实例化 OO 应用程序中的任何其他业务对象相同的方式处理,即根据依赖倒置原则。考虑到这些事情......在 State 模式中,有 different ways 可以在状态之间转换。

一种方法是管理 Context 内的转换。在这种情况下,状态彼此分离:一个状态不知道其他状态存在。 Contexthandle()(或 action())方法返回后启动转换(如有必要)。这并不一定意味着 Context 知道具体的 State 实现。 Context 可能只是一个状态对象列表,并从一个过渡到下一个。

另一种方法是通过将每个状态链接到其后继状态来管理转换:每个状态在其构造函数中采用另一个(抽象)状态。当它想要转换时,它会在 Context 上设置后继。在这种情况下,Context 不知道转换逻辑,也不知道有多少可用的状态。