【转】state模式与strategy模式的区别


在看重构一书,里面有这么一段:

 所以去网上查看一下区别。  

     原文链接:https://www.douban.com/note/202956377/?type=rec           mark~

     这几天在重温《Desigh Patterns: Elements of Reusable Object-Oriented Software》。其中state模式与strategy模式十分相似(最起码它们的类图——示意图是一样的),所以总结一下以加深记忆。
    State模式的目的是使对象在其内部状态发生改变时,对象的行为也相应发生变化。书中举的例子是关于TCP链接的。我们知道一个TCP链接的状态有:建立、监听、关闭等。当TCP链接处于不同状态时,其对一些操作(例如打开链接)的反应也是不同的,所以TCP链接自身需要一个State对象。


       如上图所示,State模式的参与角色有Context、State以及ConcreteState。Context是State模式的上下文,在TCP链接例子中就是TCP链接自身。它定义接口并向客户暴露,同时维护ConcreteState实例以标识自身状态。State是状态的抽象类或接口,它定义了一组具体状态都遵循的方法(例如TCP链接例子中的打开链接操作)。ConcreteState表示真实的、不同的状态,它继承或实现State定义的方法。假设一个TCP链接处于监听状态,则这个监听状态就由一个ConcreteState对象表示。

    Context、State与ConcreteState的协作关系如下:
    1. 当Context接收一个状态相关的操作时,它会将方法代理给表示当前状态的ConcreteState;
    2. 当State对象需要上下文数据时,Context可以将自身作为参数传递给State的方法;
    3. Context向客户暴露接口,而State不向客户暴露;客户在初始化Context时可以配置一个State对象,但之后客户就不能再直接操作State了;
    4. 只有Context与ConcreteState才可以决定在什么样的情况下,状态能变成什么样子。
    使用State模式可以很清晰地划分不同行为模式。因为ConcreteState的存在,使得新出现的状态更易添加。第二,使用State模式使得对象状态的变迁更加清晰。最后,如果State对象没有实例相关的内部属性,则不同Context之间可以共享State对象(使用Flyweight模式)。

    Strategy模式的目的是使一组相关的算法单独封装,并可相互替换。通过Strategy模式,算法的变更与进化可以独立于使用它们的客户。


    如上图所示,Strategy模式的参与角色有Strategy、ConcreteStrategy以及Context。Strategy声明了所支持的算法的公共接口。上下文(Context)通过调用这些公共接口来执行ConcreteStrategy实现的算法逻辑。ConcreteStrategy实现Strategy定义的算法接口。Context是上下文,它初始化时会配置一个ConcreteStrategy对象,并保持对这个ConcreteStrategy的引用。当然,Context也可以定义一个接口,使Strategy对象可以访问它自身的数据。

    Context、Strategy与ConcreteStrategy的协作关系如下:
    1. Strategy与Context进行交互,以实现算法的选择;当特定算法被调用时,Context可以传递其所需的数据过去;当然,Context也可以把自己作为参数传递过去(这可以实现Strategy对Context的回调);
    2. Context会直接传递客户的调用给Strategy对象;客户往往执行ConcreteStrategy对象的创建,以及对Context的配置;然后客户只与Context进行交互;客户经常会有一组ConcreteStrategy来选择。
    使用Strategy模式可以有效组织相关算法,并且使新算法的添加更加容易。另外一点,对于面向对象编程尤为重要的是,通过Strategy算法可以大大降低条件判断语句(if-else、switch等)出现的情况。第三,使用Strategy模式时,客户必须知道不同算法的存在

    最后总结一下:一言以蔽之,State模式下的多种状态对客户来说是透明的,而Strategy模式的不同算法通常对客户是不透明的。当对象的内部状态变迁,是由其自身决定的,而不是由客户决定的(或者客户并不知情),同时对象在不同状态下的行为也不一样时,则最好使用State模式;如果对象自身并不保存什么状态,而是由客户根据不同的情况去选择不同的算法,则最好使用Strategy模式。这样不同的算法对于客户来说都是可知的,并可以进行选择之后的这段E文来自网络,讲的也相当不错哦~ The state and strategy patterns are similar in the sense that both of them encapsulate behavior in separate objects and use composition to delegate to the composed object to implement the behavior and both of them provide the flexibility to change the behavior dynamically by changing the composed object at run-time. But there are some key differences : 1. In the state pattern, the client knows nothing about the state objects. State changes happen transparently to the client. The client just calls methods on the context, the context oversees its own state. Because the client is not aware of the state changes, it appears to the client as though the context is instantiated from a different class each time there is a change in behavior due to a state change. The object will appear to change its class as the official definition of the pattern states. The pattern is built around a well-defined series of state transitions. Changing state is key to the pattern's existence. 2. Even though the strategy pattern provides the flexibility to change behavior by changing the composed strategy object dynamically, mostly there is an appropriate strategy object already set for each context. ie even though the pattern provides a way to change the composed strategy object dynamically, there won't be much of a need for it. Even if it has to be done, it is the client that does the change. The client will call the setter method on the context and pass the new strategy object. Thus behavior changes are NOT transparent to the client and are initiated and controlled by the client. The pattern does not encourage a series of well-defined behavior changes like the state pattern. The client knows about the strategy objects and will usually set the appropriate strategy object in the context while creating it. The client controls what strategy object the context uses, but in the state pattern, the client knows nothing about the state object(s) that the context uses

    后记:2012年3月8日,部门开周会,大家又讨论了下两种模式的异同。现在补记如下:
    1. State模式的状态是可穷举的,一般数量不多,在Context初始化时就全部装载了,并在运行时产生变迁;Strategy模式的算法也是在Context初始化时装载的,但一般只装载一种算法,且在运行时不变话;
    2. State模式的ConcreteState有可能包含实例自身的状态信息,这种情况下State不能共享;如果State不包含实例自身的状态信息,则可以共享State(使用Flyweight模式);Strategy模式的ConcreteStrategy一般不包含实例自身的状态信息,可以共享;
    3. State模式与Strategy模式将不同的分支情况,放入不同的类。虽然会增加程序的类数量,但如果处理得当,则可以更加清晰地表明代码意图,使新分支情况的增加更加容易。

猜你喜欢

转载自wwy0612.iteye.com/blog/2304057