Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 什么是最好的方法,使用;“国家”;设计模式,改变状态?_Design Patterns_Oop - Fatal编程技术网

Design patterns 什么是最好的方法,使用;“国家”;设计模式,改变状态?

Design patterns 什么是最好的方法,使用;“国家”;设计模式,改变状态?,design-patterns,oop,Design Patterns,Oop,我目前对州设计模式的理解基本上是这样的: 在对象中封装处于特定状态的对象的所有行为。将请求委托给“当前”状态对象 我的问题是:处理状态转换的最佳方式是什么?在我的例子中,“当前”状态对象很可能是决定我们需要转换到哪个其他状态的对象。我想到了两种实现方法: state objects方法可以返回一些特定的值,这意味着“我正在请求状态转换”。然后,主对象可以查询当前状态以确定我们应该转换到哪个新状态,调用ChangeState(),然后将原始请求路由到新状态 状态对象本身可以调用父对象上的Chang

我目前对州设计模式的理解基本上是这样的:

在对象中封装处于特定状态的对象的所有行为。将请求委托给“当前”状态对象

我的问题是:处理状态转换的最佳方式是什么?在我的例子中,“当前”状态对象很可能是决定我们需要转换到哪个其他状态的对象。我想到了两种实现方法:

  • state objects方法可以返回一些特定的值,这意味着“我正在请求状态转换”。然后,主对象可以查询当前状态以确定我们应该转换到哪个新状态,调用
    ChangeState()
    ,然后将原始请求路由到新状态

  • 状态对象本身可以调用父对象上的
    ChangeState()
    ,然后将导致状态更改的请求传递给新对象

  • 场景2的优点是,主对象只需要将请求委托到“当前”状态(它将在内部处理任何必要的状态转换)。这也许也不那么明显


    我希望有更好的方法来处理这种情况。你觉得怎么样?

    我更喜欢state方法返回新的state对象(它减少了耦合,更适合于S.O.L.I.D.原则)

    以下示例(此想法用于实际项目):


    我认为您可能将自己局限于只考虑实现状态模式的对象(上下文对象和状态对象)。情况并非如此,还涉及其他对象(客户机)。持有对上下文对象的引用的客户机应该负责转换状态,这是可能的

    考虑这个虚构的例子:

    // Paintbrush is the context object
    class Paintbrush {
        // The State object, ColourState would be the abstraction
        private ColourState colourState; 
    
        // ... other class stuff
    
        public paint() {
            // Delegation to the state object
            this.colourState.paintInYourSpecificColour(); 
        }
    
        public void setColourState(ColourState newState) {
            this.colourState = newState;
        }
    }
    
    对于上下文对象来说,这应该是足够的实现了。请注意,
    colorstate
    Paintbrush
    类都不知道状态转换。这是为了减少责任的数量,以及提供更灵活的设计

    基本上,状态的改变可能是调用类的责任。如何在代码中真正实现这一点是实现细节,但需要注意的是,上下文对象和状态对象都不负责转换状态

    我试图确保我没有使用斯特劳曼论点,但我将继续使用这个例子。假设在不同的点上,您想要绘制不同的图案,并且所使用的颜色必须按照特定的顺序,您的客户将决定何时更改状态,如下所示:

    public void paintRainbow() {
        paintbrush.setColourState(new RedColourState());
        // do painting...
        // Change state to next colour
        paintbrush.setColourState(new OrangeColourState());
        // Chane state again, and so on...
    }
    
    您可以拥有由状态或上下文对象指定的颜色顺序,即拥有名为
    RainbowPaintbrush
    Paintbrush子类,它将选择下一种颜色。或者您的状态对象可以选择下一个状态,在这种情况下,您必须有一个
    红色彩虹颜色状态
    ,它知道下一个状态是
    橙色彩虹颜色状态
    ,依此类推。但这两个示例的问题是,您必须进入并(通过扩展)修改上下文和状态对象,以实现不同的转换集。但是,如果两者都不知道转换,并且这是调用类的责任,那么这可以在不更改状态或上下文对象的情况下完成。即

    public void paintChessboard() {
        paintbrush.setColourState(blackColourState);
        // do painting...
        // change state
        paintbrush.setColourState(whiteColourState);
        // etc...
    }
    
    这是一个简化的例子,但通常都成立

    快速阅读维基百科上的内容可以看出,各个州都知道下一个州,所以我认为这样做并不无效。我想总的来说,这是一个权衡,你希望控制在哪里,以及它将如何适应你的问题。这就是使用具体的状态对象进行转换如何适合我的跛脚示例:

    public class RedRainbowColourState implements ColourState {
        public void doPaint(Paintbrush paintbrush) {
            // do painting
            ColourState nextStateInRainbow = new OrangePaintbrushColourState();
            paintbrush.setColourState(nextStateInRainbow);
        }  
    
    但请注意,使用这种方式在所有状态之间进行转换所需的状态类数量激增。然而,这里的一个优势是,客户可以免除如何创建单个状态的责任和知识。在你的情况下,这可能是更好的过渡方式



    总之,您可以让各个状态执行转换,甚至是上下文对象。另一种选择是让客户端处理状态转换。

    您的一个标记拼写错误-我无法修复它,因为我没有足够的代表。正如您提到的,
    当前的
    状态决定下一个状态,那么第二种方法不仅是一种更好的方法,而且也是正确的方法。仅供参考:设计模式思维导图:你能解释一下这是如何与坚实的原则更加一致并减少耦合的吗?谢谢
    public class RedRainbowColourState implements ColourState {
        public void doPaint(Paintbrush paintbrush) {
            // do painting
            ColourState nextStateInRainbow = new OrangePaintbrushColourState();
            paintbrush.setColourState(nextStateInRainbow);
        }