
//Strategy: a strategy without state is just a function,
//so a pointer to a function plays the interface
typedef int (*Strategy)(int a, int b);
//ConcreteStrategy
int addStrategy(int a, int b) {
return a + b;
}
//ConcreteStrategy
int subtractStrategy(int a, int b) {
return a - b;
}
//Context
typedef struct {
Strategy strategy;
} Calc;
int calcExecute(const Calc *calc, int a, int b) {
if (calc->strategy == nullptr) {
return 0;
}
return calc->strategy(a, b);
}
void calcSetStrategy(Calc *calc, Strategy strategy) {
calc->strategy = strategy;
}
Calc calc = {nullptr};
int result1 = calcExecute(&calc, 5, 3);
//result1 is 0
calcSetStrategy(&calc, addStrategy);
int result2 = calcExecute(&calc, 5, 3);
//result2 is 8
calcSetStrategy(&calc, subtractStrategy);
int result3 = calcExecute(&calc, 5, 3);
//result3 is 2
printf("result1 is %d\n", result1);
printf("result2 is %d\n", result2);
printf("result3 is %d\n", result3);
Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.Read moreThe problem. A shop calculates the cost of delivery: by weight, by distance or at a fixed price. If one method holds all the ways in a chain of conditions, it grows with every new way. A change to one way can break the others, and no way can be tested alone. The idea. Each way of doing the job becomes a separate object, called a strategy. All strategies have the same shape: the same inputs and the same kind of result. The object that needs the job done, called the context, holds one strategy and calls it. It does not know which strategy it holds. The client code chooses the strategy and can replace it at any time. How to read the example. Each concrete strategy is one algorithm, and all of them take the same inputs. The client code chooses a strategy. The code that uses the strategy only calls it and does not know which one it received. In most examples the same two numbers give a different result after each change of strategy. Most of them also give an answer for the case with no strategy. In some languages a strategy is simply a function. When to use it. Use Strategy when there are several ways to do one job, and the choice depends on the user, the data or the settings. Do not use it for one algorithm that will not change. Strategy looks like State, but the difference is who makes the choice. Here the client code chooses the algorithm from outside, and the strategies know nothing about each other. In State, the object moves from state to state by itself. A common mistake. Making the context check which strategy it holds. The conditions then return, and the pattern loses its purpose. The context must only call the strategy. |