策略和状态设计方法之间的区别,一个状态如何知道其前身?

时间:2018-12-31 06:21:22

标签: algorithm design-patterns

我在refactoring.guruState页面的Strategy网站上了解了状态和策略设计模式。作者说

  

此结构看起来类似于“策略”模式,但有一个关键的区别。在国家模式中,特定国家可能彼此了解,并开始从一个国家过渡到另一个国家,而策略几乎永远不会彼此了解。

作者还说,ConcereteState类存储一个变量context,它是Context类的对象,并且通过该变量,各州可能彼此了解。

有两件事我无法理解:

  1. 一个州如何了解其前身?
  2. 我应该在哪里实现状态之间转换的逻辑?例如,通过输入state1a移至state2,并通过b移至state4,必须在哪里实现此逻辑?

这是我用php语言实现的策略的简单实现

<?php
class Algorithms{
    public $algorithm;
    function __construct(AlgorithmsInterface $algorithm){
        $this->algorithm = $algorithm;
    }

    public function run(){
        $this->algorithm->run();
    }
}

interface AlgorithmsInterface{      
    public function run();
}

class Algorithm1 implements AlgorithmsInterface{
    public function run(){
        print "Algorithm1";
    }
}

class Algorithm2 implements AlgorithmsInterface{
    public function run(){
        print "Algorithm2";
    }
}


$payment = new Algorithms(new Algorithm2());
$payment->run();

这是我实现的状态设计模式的简单实现

<?php
    interface State{
        public function execute();
    }

    class Context{

        public $state;

        public function __construct(State $initialState){
            $this->state = $initialState;
        }

        public function changeState(State $state){
            $this->state = $state;
        }

        public function execute(){
            $this->state->execute();
        }
    }

    class State1 implements State{
        public function execute(){
            print "This is State1";
        }
    }

    class State2 implements State{
        public function execute(){
            print "This is State2";
        }
    }

    $initialState = new State1();
    $state2 = new State2();
    $context = new Context($initialState);
    $context->execute();
    $context->changeState($state2);
    $context->execute();

?>

在状态和策略之间,我看不出太多区别。我确切地知道了这些策略的意图。除此之外,代码中遗漏了状态之间的移动逻辑以及状态应了解其父级的方式。

1 个答案:

答案 0 :(得分:1)

从您的示例中,这两种模式看起来非常相似。但是,状态设计模式的示例并不是真正的状态设计模式,因为您是从外部设置状态的。 典型的状态设计模式在内部更改状态,并且通常将更改委派给状态本身。 让我们看一下简单的切换按钮。它具有状态,按下状态的方法以及描述当前状态(toString())的方法:

class ToggleButton {
    enum State {
        ON {
            public State press() {
                return OFF;
            }
         },
         OFF {
             public State press() {
                 return ON;
             }
         };
         abstract public State press();
    }

    State state = State.OFF;
    public void press() {
        state = state.press();
    }
    public String toString() {
        return "Device is " + state;
    }
}

因此从外部您没有设置状态,所以您不知道它处于哪种状态以及它将如何反应。您使用:

button.press();
System.out.println(button);

所以关键的区别是,对于策略,您从外部传递策略,然后让您的对象执行某些操作(不会改变策略),因此这是粘性委派。

但是状态设计模式的目的是,状态应该经常在内部发生变化,并且随着状态的变化行为也会发生变化。因此,即使我们在执行某些任务之前设置了某个状态,它也可能在任务完成期间在内部发生变化(通常会发生变化)。 这是一种实现状态多态的方法。还要注意,它通常与状态自动机有关。