You'll want to look at Objective-C's protocol mechanism. Here's a simple protocol with a single required method:
@protocol Strategy <NSObject>
@required
- (void) execute;
@end
Then you declare a class that fulfills that protocol:
@interface ConcreteStrategyA : NSObject <Strategy>
{
// ivars for A
}
@end
The implementation must provide the -execute
method (since it was declared as @required
):
@implementation ConcreteStrategyA
- (void) execute
{
NSLog(@"Called ConcreteStrategyA execute method");
}
@end
You can make a similar ConcreteStrategyB
class, but I'm not going to show it here.
Finally, make a context class with a property maintaining the current strategy.
@interface Context : NSObject
{
id<Strategy> strategy;
}
@property (assign) id<Strategy> strategy;
- (void) execute;
@end
Here is the implementation. The method that delegates to the strategy's -execute
method just happens to be called -execute as well, but it doesn't have to be.
@implementation Context
@synthesize strategy;
- (void) execute
{
[strategy execute];
}
@end
Now I'll make a few instances and put them to use:
ConcreteStrategyA * concreteStrategyA = [[[ConcreteStrategyA alloc] init] autorelease];
ConcreteStrategyB * concreteStrategyB = [[[ConcreteStrategyB alloc] init] autorelease];
Context * context = [[[Context alloc] init] autorelease];
[context setStrategy:concreteStrategyA];
[context execute];
[context setStrategy:concreteStrategyB];
[context execute];
The console output shows that the strategy was successfully changed:
2010-02-09 19:32:56.582 Strategy[375:a0f] Called ConcreteStrategyA execute method
2010-02-09 19:32:56.584 Strategy[375:a0f] Called ConcreteStrategyB execute method
Note that if the protocol does not specify @required
, the method is optional. In this case, the context needs to check whether the strategy implements the method:
- (void) execute
{
if ([strategy respondsToSelector:@selector(execute)])
[strategy execute];
}
This is a common Cocoa pattern called delegation. For more information on delegation and other design patterns in Cocoa, see this.