Jump to content

Talk:Strategy pattern

Page contents not supported in other languages.
From Wikipedia, the free encyclopedia

Examples do not illustrate the interaction of the Strategy with the Context

[edit]

Except of simplest toy cases, the Strategy usually needs to access the data of the Context. For example some braking algorithms may need to access car properties like car.speed, car.brake_fluid_level etc.. GoF book suggests different ways of achieving this:

  1. context passes the data to the strategy operations
  2. context passes itself as an argument to the strategy operations
  3. strategy stores a reference to the context, eliminating the need to pass anything at all

In case of (2) and (3), the Context must define an interface for accessing its data.

— Preceding unsigned comment added by 86.2.5.138 (talk) 21:09, 27 June 2015 (UTC)[reply]

Bad Concept

[edit]

"classes should be open for extension but closed for modification." The example, shows a change of Behavior (ABS/ normal brake), but this is a variation of behaviour. Not a extension. We always talk about Brake... Extension means that we can ADD another Behaviour, like OpenCarDoors().

"Variation" Car : brake() --> switch to ABS / Normal Brake

"Extension" Car : brake() --> switch to abs/normal brake (Is a variation of brake(), but Brake() is fixed by interface) OpenDoors() <-- Adding a new method, means Extension...

Poor Examples

[edit]

Does anyone else think these examples don't exactly convey the encapsulation and alternating of algorithms? All I see are some roundabout "switch" statements. Perhaps if the algorithm parts of the examples weren't so throwaway, ie: instead of just tracing "Doing the task", the interfaces actually implement more functions and the article walk us through a simple yet concrete example. Perhaps the traversal of trees with different iteration algorithms - that would be a good, useful, simple example.


Agreed. I personally did not understand the article fully due to the lack of meaningful examples. Assuming I'm not totally wrong in my understanding, would a set of sorting algorithms perhaps be a better example? At run-time, the algorithm to call may then be chosen based on whether the data to sort is expected to be mostly disordered (e.g. quicksort), mostly ordered, mostly disordered and generated on the fly (e.g. treesort), low in quantity (e.g. bubblesort), etc..... Alternatively, having differently optimised versions of the same algorithm, and deciding which to call at run-time based on the hardware available. For example, matrix multiplication using either FPU/MMX/SSE*/AVX, etc. 176.253.193.141 (talk) 19:12, 28 March 2013 (UTC)[reply]


Agreed - in the C# 'operations' example, the Page_Load function (which I guess is the 'client' in this case) makes explicit use of the Plus and Minus classes anyway, so this (without context) is not so much an application of the strategy pattern as a verbose way of writing a + b and a - b. Also Page_Load is written under a namespace, not a class, so this is not valid C#. — Preceding unsigned comment added by 195.224.53.130 (talk) 12:22, 16 December 2015 (UTC)[reply]

Why not code the same example, in multiple languages?

[edit]

I always wonder why for design patterns on wikipedia, why not choose one example, make the UML diagram for it and implement it in multiple languages, instead of having a different example in each language. That way the reader can compare the examples if he/she doesn't understand. It's almost the case here, most examples are the same, but not the UML and the Python example

Gabriel - June 10th 2008 —Preceding unsigned comment added by 83.219.124.13 (talk) 08:35, 10 June 2008 (UTC)[reply]

Error in python code?

[edit]

... button1 = Button(sum, "Add 'em") - shouldn't this line pass in function liek the line below? button2 = Button(lambda nums: " ".join(map(str, nums)), "Join 'em") ... —Preceding unsigned comment added by Markscottjohnson (talkcontribs) 10:22, 15 February 2008 (UTC)[reply]

sum is a built-in Python function, so there's no bug there. --MichalKwiatkowski (talk) 16:20, 17 February 2008 (UTC)[reply]

War

[edit]

I do not like the war comparison, I'd rather describe the same thing as a gaming situation. Somebody else has an opinion about that? --Bjoern.thalheim 09:36, 15 November 2005 (UTC)[reply]

The war is an example of a game.

Strategy Pattern using delegates in C#?

[edit]

The example says that it is in C#. Would it be possible to do this pattern in C# using delegates, and if so, should that be included in the article? The two concepts seem closely related at first glance. 168.209.98.35 15:17, 18 February 2006 (UTC) If this is a democracy, I vote against including the topic about delegates. Using delegates "gets around" using polymorphism and reduces the implementation to a list of methods. frankfazzio@yahoo.com — Preceding unsigned comment added by 128.170.224.10 (talk) 15:41, 6 March 2012 (UTC)[reply]

C#??

[edit]

I think it would be better to have the code example in a more "traditional" language, like C++.

Since there are more people knowing C++ as opposed to C#, it would reach more people.

Definitely agreed 144.173.6.66 16:11, 3 June 2006 (UTC)[reply]

For most simple code if you understand C++ you understand C# but this doesn't happen in the opposite way so I think C# it's ok.

Example not concrete

[edit]

An example needs to be a concrete realization of what the abstract idea is capable of. Here we're shown an example of how a "strategy" can perform different "executions" depending on the "context," but the example entities are named Strategy, Execute, and Context. That's hardly a concrete realization of this concept.

Plus, the code itself seems too trivial to get the point of the object across. Three different contexts are created, and their execute methods are called. This code easily devolves into just calling three different methods. An example where the strategy design pattern actually *improves* upon a simpler design, rather than needlessly complicating it (due to the sheer simplicity and contrived-ness of this code), would be better.

The class diagram spells "concrete" incorrectly. — Preceding unsigned comment added by 194.201.25.22 (talk) 11:12, 28 June 2011 (UTC)[reply]

IInterface

[edit]

C# interfaces should always be named with a prefixed I such as IObserver.

This is not true. It is a common convention though. travelan (talk) 11:32, 26 January 2009 (UTC)[reply]

previous issues

[edit]

C# vs. C++
the example should stay in C#. In the future, C++ will fade out as one of the top-liked languages. As i see many up-and-coming programmers, the tendency is towards high level, true OO languages like C# and Java. However, adding an additional example in C++ would, of course, not be useless.

Multiple instances
This example does not, at all, show the strategy design pattern. It shows a simple case of Realization (the UML relationship for implementing an interface). What would be useful is creating a mutator in the Context class:

//if i remember the C# syntax for accessor/mutator
protected Strategy Strategy{
  get { return strategy;  }
  set { strategy = value; }
}

so that way, you can keep one instance the Context class alive, and then dynamically set it's strategy. Then it would be the Strategy Design Pattern because it dynamically changes the algorithm the Execute() method executes.

C++ code: adding later

[edit]

I am currently in the process of adding formatted C++ code for Design Patterns. An example of the style can be seen in this topic: Bridge pattern. The code for this topic is currently being reviewed.


EDIT 21:25, 12 July 2006 (UTC)

Done, C++ code added.

Vladimir Bosnjak 14:31, 11 July 2006 (UTC)[reply]


It's not really C++-way, if nobody objects I'll replace this with templated version. --217.80.161.150 (talk) 13:43, 6 January 2009 (UTC)[reply]

Deleted C# code

[edit]

I've reinserted and reformatted the C# code that was deleted. Santorumm, what basic structures that you indicated in your edit summary does C# lack that are present in C++? I'll see if I can add a C# delegate example and pair up header files with their .cpp counterparts later. Also, Java is similar enough to C# that a separate Java example would be superfluous. Supadawg (talkcontribs) 02:42, 1 September 2006 (UTC)[reply]

It is missing things such as ArrayList and LinkedList containers, which would make a simple example illustration of the fundamental pattern difficult.. Santorummm 15:23, 1 September 2006 (UTC)[reply]
I don't mean to sound rude, but have you ever programmed in C# before? The ArrayList is one of the most commonly-used classes. Also, it's implemented as a linked list, making a separate class redundant. Why do you need them, anyway? The C++ example uses plain C-style arrays, which C# has also, which would be faster. Supadawg (talkcontribs) 20:27, 1 September 2006 (UTC)[reply]
On certain code being superfluos: where's the limit? Give me (and many other coders offcourse) a proper UML presentation and I won't need code examples at all. This may not be the case in all possible cases but I hope the point is made. Or give me code in C# (for example) only, and I won't be needing Java or C++ code at all to port the code. So once again, I wonder where the limit is. Vladimir Bosnjak 20:32, 22 September 2006 (UTC)[reply]

Syntax coloring

[edit]

The current syntax coloring in the C++ code makes it impossible to edit, and only a little easier to read. I think it should be removed. Supadawg (talkcontribs) 16:20, 4 September 2006 (UTC)[reply]

I'll give it another couple of days, then remove it if no one replies. Supadawg (talkcontribs) 20:37, 6 September 2006 (UTC)[reply]
No objections, so I'll go ahead and remove the syntax coloring. Supadawg (talkcontribs) 00:48, 10 September 2006 (UTC)[reply]
No problem. My upcoming snippets will not be html formatted anymore since you made a valid point. I'll use the ANSI style formatting only (tabs, indents etc).You may be interested in removing the coloring for the Template Method pattern as well. Just preserve ansi style, 2 space tabs please. Vladimir Bosnjak 18:52, 22 September 2006 (UTC)[reply]

Language Wars

[edit]

I believe that the samples of this pattern in as many languages as desired should be allowed. However, I believe that one stipulation should be adhered to. All code sample should be as high a quality as possible and as concise as possible.


On top of that, I notice that some of the Design Pattern pages have no examples at all. (Feel free to move this thread to a more general article.) Let's try to have at least one example or two examples on each page -- preferably one in a language without first-class functions, and one in a language with them. Here's a humble recommendation... High-priority:

  • Java or C# -- whichever gets written first; they're both good examples.
  • Python or Ruby -- both are popular, look like pseudocode, and have first-class functions.

Nice to have:

  • JavaScript/ECMAScript -- Web programmers deserve a chance to educate themselves, too

Lower priority:

  • The other of C# or Java that wasn't already implemented
  • C++ -- the original book used C++ examples... so why duplicate the effort? Plus, a real-world, secure C++ example suitable for copy-and-paste often looks much different from a contrived, educational, naive implementation.

Bottom priority:

  • Languages without built-in constructs for OOP
  • Proprietary languages (e.g. Actionscript -- just use JavaScript!) -- there's usually an equivalent in the top 20 of the Tiobe language popularity index.
  • Languages not in the Tiobe top 20

Style guidelines:

  • Do something slightly different in each example -- don't directly translate.
  • Try to avoid distracting language features. (My Python example uses a built-in function (sum) and lambda+map, which is brutal, but it does save a couple of trivial function definitions...)
  • Minimize whitespace and newlines where it doesn't hurt clarity. It's nice if it fits on one screen.
  • Indicate where you would encounter this pattern in a real program, if possible. Name variables accordingly.
  • Test the example first, and include the output in the comments

EricTalevich (talk) 19:54, 29 November 2007 (UTC)[reply]

I don't agree with you that C++ shouldn't be included in the examples. Wikipedia is an encyclopedia, so it should contain information that's compatible with the source. Besides, the gang of four did not decide to use C++ for no reason! C++ is one of the few programming languages that allow multiple inheritance for example (MI is used, or at least usable, in a few Design Patterns and it greatly enhances readability. MI also allows better conversion from UML to code.). travelan (talk) 11:33, 26 January 2009 (UTC)[reply]

Strategy for Algorithms with different outputs?

[edit]

I've seen very different viewpoints on the internet about how the Strategy pattern should be used.

Some seem to say to only use the Strategy pattern as long as each algorithm produces the same output. Others say that the Strategy pattern can/should be used for any variety of algorithms that may be run on an object, even if a given pair of algorithms may produce a different output.

Different strategies will in general prodice different outputs. That's one reason why one would want to be able to change strategies. Performance, as you discuss below, or memory utilization may be other reasons. --71.214.221.153 (talk) 22:19, 27 March 2010 (UTC)[reply]

For example, a QuickSort and a BubbleSort on the same simple list of data would produce the same ordered list, so according to the "same output" theory they'd be good candidates for the Strategy pattern. However, what if one wanted to (for example) create two algorithms that ordered objects by some complex ranking scheme, and the outputs of those two were different? As an example, let's say you could access the source for Google and Yahoo's search relevancy rankings in relation to a specific keyword and list of websites, and you made algorithms based on this to sort the given list of websites by relevancy for Google and Yahoo respectively. Would these two algorithms also be candidates for the Strategy pattern, or is there a more appropriate pattern to use?

Is there an expert watching this conversation who has an answer? It may be worth putting on the page if you do, because I'm sure there's others like me who came to this page hoping to find the answer to that (as well as alternative Design Patterns that would fit the bill if one of the scenarios described above don't actually fit into the intent of the Strategy pattern).

-Jack Colorado 75.39.171.37 01:07, 13 November 2007 (UTC)[reply]

It's still Strategy. Java's Comparator interface or C#'s IComparator, for instance, are interfaces for specifying an ordering strategy within a sort. Strategy is not just a way of specifying a private implementation detail in order to make trade offs in performance or whatever. It's a way to pass in a function to be used as piece of a larger algorithm. That's why the article says that first class functions are a replacement for this pattern.

Hmm, fascinating. Aye, this is good information, thanks for the post about it... it definitely clears things up for me. I think the kind of more explicit definition you gave here would be useful on the page. Saying that first class functions are a replacement is good if you know what a first class function is and how it fits in here, but I think it would be good to just outright say what you said above ("It's not just a way of specifying a private implementation detail..."). If you could elaborate on it a little more, I'd like to see a variant on your description on the page itself personally.

-Jack Colorado 24.10.88.246 (talk) 04:21, 18 November 2007 (UTC)[reply]

Invisibility claim for first class functions

[edit]

This pattern is invisible in languages with first-class functions.

In general one declares an Interface, not just a function, that defines a set of functions a strategy must implement. See for instance, the sizers in wxWidgets. I don't see how a language that has first-class functions makes this invisible. Justify the claim with a reliable reference. I doubt you'll find one. --71.214.221.153 (talk) 22:12, 27 March 2010 (UTC)[reply]

What is actionscript doing here?!

[edit]

I'm not sure why it is here?--Michael miceli (talk) 20:58, 9 April 2008 (UTC)[reply]

ActionScript is approximately equal to JavaScript, and both have first class functions - so the example isn't even correct! —Preceding unsigned comment added by 81.86.77.35 (talk) 23:53, 17 August 2008 (UTC)[reply]

All in the favor of removing ActionScript from the examples? travelan (talk) 11:33, 26 January 2009 (UTC)[reply]

I'd prefer to repair the example more than remove it. It doesn't seem to be correct. —Preceding unsigned comment added by 205.223.231.72 (talk) 08:47, 5 March 2009 (UTC)[reply]

Overlaps with Delegation pattern

[edit]

Aren't these two basically the same? 138.246.7.155 (talk) 13:12, 6 November 2008 (UTC)[reply]

No. You could do the same things with them, and they can look and act the same, but the patterns are different. While the Strategy Pattern is used to define a strategy for an action (or more actions), the Delegation Pattern is used to delegate the responsibilities of a class to another class. The Strategy Pattern describes a way to declare one or more behaviors for an object. The Delegation Pattern describes a way to spread and delegate code sections that should be located in an other location than the class that's using that code. (Due to refactoring or design) travelan (talk) 11:39, 26 January 2009 (UTC)[reply]


Closures

[edit]

It seems to me that something important is glossed over in the examples. All the examples (as far as I can tell) can be implemented using "simple" (C-like) function pointers; that is, the strategies don't hold any context about state. This makes, for example, the C++ version look overly complicated for the behaviour granted, as the function pointer version can drop all the strategy class definitions and initializations. The advantage of using a class or closure is that the strategy can store state. —Preceding unsigned comment added by 86.22.75.44 (talk) 20:57, 21 February 2010 (UTC)[reply]

You are correct. The examples don't really do justice to the pattern. The article should be reworked.

--71.214.221.153 (talk) 22:22, 27 March 2010 (UTC)[reply]

Note in the same respect, that it may be claimed to use the Strategy pattern in a functional programming style. See for example : Functional Programming in Java, Harnessing the Power of Java 8 Lambda Expressions (ch. 4, passim and page 66), by Venkar Subramaniam, where the pattern is

claimed to be in use in cases where a lambda is passed in to some function using Java Stream. Ptyxs (talk) 17:38, 19 December 2014 (UTC)[reply]

Criticism?

[edit]

An interesting criticism of this pattern:

http://coderoom.wordpress.com/2010/06/23/criminal-overengineering/

I don't know whether the criticism is valid (I program microcontrollers with 128 bytes of RAM, so most design patterns simply don't apply) but I couldn't help noticing that none of the five or so Wikipedia pages on design patterns I checked has anything bad to say about them. Guy Macon 00:42, 24 June 2010 (UTC)[reply]

I agree that it would be nice to see criticisms. I perhaps would not word it as "bad things about this pattern," as I think that patterns are great in some situations and bad in others. Some of the other design pattern articles seem to have sections that discuss the side effects of their use, or good and bad scenarios to apply this pattern. Perhaps that good/bad use case approach could be applied here? On a similar note, a lot of patterns have variations that make them much more effective in certain situations. It would be great if we could describe common variations as well. Crabpot8 (talk) 19:40, 19 July 2010 (UTC)[reply]

Ruby example not thread safe, also kind of ugly

[edit]

Ruby example is not thread safe, is it?

self.class.send :include, strategy

this makes it switch strategy in all objects, in all threads... —Preceding unsigned comment added by 87.119.57.129 (talk) 09:32, 28 June 2010 (UTC)[reply]

It is not just thread unsafe, it is incorrect for exactly the reason you cited. It switches strategy for all objects. To demonstrate, run a.execute after b = Context.new(StrategyB). It will use StrategyB, not StrategyA. The correction is to change the constructor:

class Context
  def initialize(strategy)
    singleton = class << self; self; end
    singleton.send :include, strategy
  end
end

This includes the strategy in a separate singleton class for each Context instance.

If there is no comments in a week (i.e., Nov 17, 2010), I'll change the forementioned Ruby example. AustinBlues (talk) 17:04, 10 November 2010 (UTC)[reply]

Purpose of context in strategy pattern is unclear

[edit]

It would be nice to see a section discussing the context object and what it is for. (I am not sure). It seems to be related to the need for some strategy patterns to store information. Aka some algorithms have a memory, and some don't. It seems to be that this is what the Context is utilized for, but a section on this distinction with some external references to algorithms that use or don't use memory would be nice. I believe the Gang of Four book has a few examples that attempt to apply different line formatting examples to a word document. Sorry for poor grammar, in a hurry. Crabpot8 (talk) 19:35, 19 July 2010 (UTC)[reply]

"The UML class diagram for the Strategy pattern is the same as the diagram for the Bridge pattern."?

[edit]

They look differend to me.

Is there any reason to say they are same?

Absolutely not. This claim is, without a doubt, false.

Typo in UML diagram

[edit]

Spelling is wrong, should say "concrete", not "concreate"

Possible duplicate: Criteria pattern

[edit]

While searching for this pattern, I initially looked for "applying criteria" and found this article https://en.wikipedia.org/wiki/Criteria_Pattern. it seems to be a duplicate of this one and has only minor differencies (filtering and selecting instead of filtering only). it was written by one guy who cited himself as the author of the pattern and linked to some article from 2011 (see history). could someone more familiar with patterns look into this and create a redirect to this article or improve the other article, please? 109.192.57.59 (talk) 22:32, 29 September 2014 (UTC)[reply]

Improve Java Example

[edit]

I think it would be better if the Java example had a strategy that effected the add() function not the billing function — Preceding unsigned comment added by 84.94.147.201 (talk) 15:11, 26 May 2015 (UTC)[reply]

Further to the above, the current example is somewhat confusing in that if you order some drinks during normal hours and some during happy hour, you would not expect to be billed at whatever the last applied rate is. Perhaps use a better example, or at the very least don't switch strategies for a given customer half way through (which means you can't demonstrate some of the patterns' power)? Jakehoward12 (talk) 10:17, 9 June 2015 (UTC)[reply]

Should be clear if a strategy pattern can or cannot have more than one method

[edit]

It's still not clear to me and I can't find it anywhere. Also there should be a link to the proper pattern, if any.

For example, if I have two methods that strongly share a theme:

public interface IStrategy {  
   void activate(GameObject x);
   void deactivate(GameObject x);
}

It makes no sense to decouple each one because, for example a SwitchStrategy could turn on/off a light switch/lever, and a PushPullStrategy could push/pull different kind of objects... but there is no case in which I could "turn on" and "pull" an object.

If they're strongly related, should a strategy pattern apply?

I thought of an abstract factory of strategies, but that's just cumbersome.

Thanks

--186.19.69.168 (talk) 15:39, 24 April 2016 (UTC)[reply]

Yes, there can be multiple methods.
What's important is that these methods can be represented by some abstract interface in a consistent manner. "IStrategy" doesn't work as a name or a scope because it doesn't indicate the "theme" (in your terminology) of this abstract interface. It should more specifically indicate "That which may be activated or deactivated", because that's the common aspect between all the applicable strategies.
It's also important that there is some aspect more to this strategy than merely inheritance. A Strategy pattern is there to make run-time decisions about how to act (based on observation of some external or internal state), not merely be hard-coded to do so based on the class type of the object invoked at the time. That would be just polymorphism: a degenerate case of Strategy at most. Andy Dingley (talk) 16:42, 24 April 2016 (UTC)[reply]

UML class and sequence diagram

[edit]

I would like to share the following UML diagrams I have published on Design Patterns Open Online Learning. Your comments are welcomed.

A sample UML class and sequence diagram for the Strategy design pattern.

In the above UML class diagram, the Context class doesn't implement an algorithm directly. Instead, Context refers to the Strategy interface for performing an algorithm (strategy.algorithm()), which makes the Context independent of how an algorithm is implemented. The Strategy1 and Strategy2 classes implement the Strategy interface, that is, implement (encapsulate) an algorithm.
The UML sequence diagram shows the run-time interactions: The Context object delegates an algorithm to (switches between) different Strategy objects. First, Context calls algorithm() on a Strategy1 object, which performs the algorithm and returns the result to Context. Thereafter, Context calls algorithm() on a Strategy2 object, which performs the algorithm and returns the result to Context.

Vanderjoe (talk) 19:03, 7 July 2017 (UTC)[reply]

Composition in UML Class diagram should be aggregation

[edit]

The composition on the left hand side should be an aggregation. 1. The strategies can exist without the context (so no existential dependency) 2. The strategies can be used in other contexts (so no strong ownership) 3. The original source [Gamma et al.] says so — Preceding unsigned comment added by 134.106.27.226 (talk) 11:32, 19 April 2018 (UTC)[reply]