What is the difference between Strategy design pattern and State design pattern?

前端 未结 19 1651
太阳男子
太阳男子 2020-12-02 04:06

What are the differences between the Strategy design pattern and the State design pattern? I was going through quite a few articles on the web but could not make out the dif

相关标签:
19条回答
  • 2020-12-02 04:16

    The Strategy Pattern involves moving the implementation of an algorithm from a hosting class and putting it in a separate class. This means that host class does not need to provide the implementation of each algorithm itself, which is likely to lead to unclean code.

    Sorting algorithms are usually used as an example as they all do the same kind of thing (sort). If each differing sorting algorithm is put into its own class, then the client can easily choose which algorithm to use and the pattern provides an easy way to access it.

    The State Pattern involves changing the behaviour of an object when the state of the object changes. This means that the host class does not have provide the implementation of behaviour for all the different states that it can be in. The host class usually encapsulates a class which provides the functionality that is required in a given state, and switches to a different class when the state changes.

    0 讨论(0)
  • 2020-12-02 04:17

    The difference is discussed in http://c2.com/cgi/wiki?StrategyPattern. I have used the Strategy pattern for allowing different algorithms to be chosen within an overall framework for analysing data. Through that you can add algorithms without having to change the overall frameworks and its logic.

    A typical example is that you amy have a framework for optimising a function. The framework sets up the data and parameters. The strategy pattern allows you to select algorithms such as sttepest descents, conjugate gradients, BFGS, etc. without altering the framework.

    0 讨论(0)
  • 2020-12-02 04:19

    Both Strategy and State pattern has the same structure. If you look at the UML class diagram for both patterns they look exactly same, but their intent is totally different. State design pattern is used to define and manage state of an object, while Strategy pattern is used to define a set of interchangeable algorithm and lets client to choose one of them. So Strategy pattern is a client driven pattern while Object can manage there state itself.

    0 讨论(0)
  • 2020-12-02 04:20

    This is a pretty old question, but still, I was also looking for the same answers and this is what I have discovered.

    For State pattern lets consider an example of Medial Player Play button. When we do play it starts playing and makes the context aware that it is playing. Every time the client wants to perform play operation he checks the current state of the player. Now the client knows the state of the object is playing via the context object so he calls the pause state objects actions method. The part of the client realizing the state and on what state it needs to do action can be automated.

    https://www.youtube.com/watch?v=e45RMc76884 https://www.tutorialspoint.com/design_pattern/state_pattern.htm

    In the case of Strategy pattern, the arrangement of the class diagram is same as state pattern. The client comes to this arrangement to do some operation. That is instead of the different states there are different algorithms say for example different analysis that needs to be performed on the pattern. Here the clients tell the context what it wants to do that what algorithm (business defined custom algorithm) and then performs that.

    https://www.tutorialspoint.com/design_pattern/strategy_pattern.htm

    Both implements open close principle so the developer has the capability to add new states to the state pattern and new algorithm.

    But the difference is what they are used that is state pattern used to execute different logic based on a state of the object. And in a case of strategy different logic.

    0 讨论(0)
  • 2020-12-02 04:21

    Can somebody please explain in layman's terms?

    Design patterns are not really "layman" concepts, but I'll try to make it as clear as possible. Any design pattern can be considered in three dimensions:

    1. The problem the pattern solves;
    2. The static structure of the pattern (class diagram);
    3. The dynamics of the pattern (sequence diagrams).

    Let's compare State and Strategy.

    Problem the pattern solves

    State is used in one of two cases [GoF book p. 306]:

    • An object's behavior depends on its state, and it must change its behavior at run-time depending on that state.
    • Operations have large, multipart conditional statements that depend on the object's state. This state is usually represented by one or more enumerated constants. Often, several operations will contain this same conditional structure. The State pattern puts each branch of the conditional in a separate class. This lets you treat the object's state as an object in its own right that can vary independently from other objects.

    If you want to make sure you indeed have the problem the State pattern solves, you should be able to model the states of the object using a finite state machine. You can find an applied example here.

    Each state transition is a method in the State interface. This implies that for a design, you have to be pretty certain about state transitions before you apply this pattern. Otherwise, if you add or remove transitions, it will require changing the interface and all the classes that implement it.

    I personally haven't found this pattern that useful. You can always implement finite state machines using a lookup table (it's not an OO way, but it works pretty well).

    Strategy is used for the following [GoF book p. 316]:

    • many related classes differ only in their behavior. Strategies provide a way to configure a class with one of many behaviors.
    • you need different variants of an algorithm. For example, you might define algorithms reflecting different space/time trade-offs. Strategies can be used when these variants are implemented as a class hierarchy of algorithms [HO87].
    • an algorithm uses data that clients shouldn't know about. Use the Strategy pattern to avoid exposing complex, algorithm-specific data structures.
    • a class defines many behaviors, and these appear as multiple conditional statements in its operations. Instead of many conditionals, move related conditional branches into their own Strategy class.

    The last case of where to apply Strategy is related to a refactoring known as Replace conditional with polymorphism.

    Summary: State and Strategy solve very different problems. If your problem can't be modeled with a finite state machine, then likely State pattern isn't appropriate. If your problem isn't about encapsulating variants of a complex algorithm, then Strategy doesn't apply.

    Static structure of the pattern

    State has the following UML class structure:

    PlantUML class diagram of State Pattern

    Strategy has the following UML class structure:

    PlantUML class diagram of Strategy Pattern

    Summary: in terms of the static structure, these two patterns are mostly identical. In fact, pattern-detecting tools such as this one consider that "the structure of the [...] patterns is identical, prohibiting their distinction by an automatic process (e.g., without referring to conceptual information)."

    There can be a major difference, however, if ConcreteStates decide themselves the state transitions (see the "might determine" associations in the diagram above). This results in coupling between concrete states. For example (see the next section), state A determines the transition to state B. If the Context class decides the transition to the next concrete state, these dependencies go away.

    Dynamics of the pattern

    As mentioned in the Problem section above, State implies that behavior changes at run-time depending on some state of an object. Therefore, the notion of state transitioning applies, as discussed with the relation of the finite state machine. [GoF] mentions that transitions can either be defined in the ConcreteState subclasses, or in a centralized location (such as a table-based location).

    Let's assume a simple finite state machine:

    PlantUML state transition diagram with two states and one transition

    Assuming the subclasses decide the state transition (by returning the next state object), the dynamic looks something like this:

    PlantUML sequence diagram for state transitions

    To show the dynamics of Strategy, it's useful to borrow a real example.

    PlantUML sequence diagram for strategy transitions

    Summary: Each pattern uses a polymorphic call to do something depending on the context. In the State pattern, the polymorphic call (transition) often causes a change in the next state. In the Strategy pattern, the polymorphic call does not typically change the context (e.g., paying by credit card once doesn't imply you'll pay by PayPal the next time). Again, the State pattern's dynamics are determined by its corresponding fininte state machine, which (to me) is essential to correct application of this pattern.

    0 讨论(0)
  • 2020-12-02 04:22

    Strategy: the strategy is fixed and usually consists of several steps. (Sorting constitutes only one step and thus is a very bad example as it is too primitive in order to understand the purpose of this pattern). Your "main" routine in the strategy is calling a few abstract methods. E.g. "Enter Room Strategy", "main-method" is goThroughDoor(), which looks like: approachDoor(), if (locked()) openLock(); openDoor(); enterRoom(); turn(); closeDoor(); if (wasLocked()) lockDoor();

    Now subclasses of this general "algorithm" for moving from one room to another room through a possible locked door can implement the steps of the algorithm.

    In other words subclassing the strategy does not change the basic algorithms, only individual steps.

    THAT ABOVE is a Template Method Pattern. Now put steps belonging together (unlocking/locking and opening/closing) into their own implementing objects and delegate to them. E.g. a lock with a key and a lock with a code card are two kinds of locks. Delegate from the strategy to the "Step" objects. Now you have a Strategy pattern.

    A State Pattern is something completely different.

    You have a wrapping object and the wrapped object. The wrapped one is the "state". The state object is only accessed through its wrapper. Now you can change the wrapped object at any time, thus the wrapper seems to change its state, or even its "class" or type.

    E.g. you have a log on service. It accepts a username and a password. It only has one method: logon(String userName, String passwdHash). Instead of deciding for itself whether a log on is accepted or not, it delegates the decision to a state object. That state object usually just checks if the user/pass combination is valid and performs a log on. But now you can exchange the "Checker" by one that only lets priviledged users log on (during maintanace time e.g.) or by one that lets no one log on. That means the "checker" expresses the "log on status" of the system.

    The most important difference is: when you have choosen a strategy you stick with it until you are done with it. That means you call its "main method" and as long as that one is running you never change the strategy. OTOH in a state pattern situation during the runtime of your system you change state arbitrarily as you see fit.

    0 讨论(0)
提交回复
热议问题