A core solution to a recurring problem
General structure of a design pattern solution
Pattern Name
an easy to understand label to provide a common vocabulary
Problem
explanation of when to apply the pattern
Solution
general arrangement of elements (classes and objects)
Consequences
results and trade-offs of the particular solution
Concerned with algorithms and the assignment of responsibilities between objects
The communication methods between them
Encapsulating behavior in an object and delegating requests to it
The conventional way
GetName ();
Design Pattern way
Strategy
Pattern Name
Strategy
Problem (when to use this pattern)
You need different variants of an algorithm
An algorithm uses data clients shouldnt be exposed to
Many classes are similar, differing only in their behavior
(allow algorithm to vary independent of clients)
Solution 1
using Cs typedef for functions
typedef void eogFunction (Player *pPtrs);
extern void hhcoEOGFunc (Player *pPtrs);
void
blah (eogFunction sF, Player *pPtrs)
{
(*sF) (pPtrs); // call whatever sort is passed in
}
void
main ()
{
const Int32 NUM_PLAYERS = 4;
Players thePlayers [NUM_PLAYERS];
// assume thePlayers is initialized somehow here
blah (hhcoEOGFunc, thePlayers);
}
If hhcoEOGFunc () needs more information to determine what to do, they will have to global variables (usually a poor design decision)
If the user decides to play by alternative rules (via the setup dialog box), how will you remember which function to call?
switch (eogType)
{
case NORMAL:
blah (hhcoEOGFunc);
break;
case QUICK:
blah (quickEOGFunc);
break;
case DEBUG:
blah (debugEOGFunc);
break;
}
Solution 3
Create a base class with an Execute () function
Client keeps a reference to it
It can be changed as needed, and client doesnt know what its calling, only that it is calling something
Data
can be modified for a particular objects functionality, by
calling that objects member functions only
Strategy is Abstract (or at least has 1 virtual function (Execute ())
Execute () is passed the parameters it needs, or is passed a reference to an object it can query for values
EOGFunction objects ARE objects and can be treated as such
class EOGFunction
{
public:
virtual void Sort (Players *pPtrs);
};
class hhcoEOGFunc : public EOGFunction
{
public:
virtual void Check (pPtrs);
};
class quickEOGFunc : public EOGFunction
{
public:
virtual void Check (pPtrs);
void SomeInitFunc (int, int, int);
};
Consequences
Advantages
Can create FAMILIES of related algorithms. Inheritance can be used to share in functionality (i.e. You are making CLASSES, not FUNCTIONS, so they can be treated just like any other class. Passed as parameters, instantiated and destructed, etc.)
You can use them as the working half of another class, making the front end class easier to understand
Can get rid of if-then-else and switch statements to control behavior
Gives the client choice in which implementation to use, dynamically
Drawbacks
Client must be aware of some (or all) of the strategies available in order to use them
Overhead in instantiating Strategys variables
If this is a derived class, and a bunch of other stuff is initialized that this particular implementation doesnt need, time and resources have been wasted
Increases the number of objects in a system
Summary
Use Stratgey to encapsulate an algorithm
Clients keep a reference to a base class, so they dont need to know the actual form of implementation
This allows coding for change, because
You can change your mind about what functionality should be executed, during execution of the program
You can change your mind about what parameters are important when executing the function