如何在Objective-C中创建策略模式?

Cat*_*thy 12 objective-c strategy-pattern

我需要开发一个策略模式,其中我有一个主类与其他三个类,我需要使用主类对象引用其他三个类的对象.要解决这个问题,战略模式会对我有帮助吗?如果是这样,请给我Objective-C中的语法?

Jon*_*eid 39

您将要了解Objective-C的协议机制.这是一个简单的协议,只需要一个方法:

@protocol Strategy <NSObject>

@required
- (void) execute;

@end
Run Code Online (Sandbox Code Playgroud)

然后声明一个满足该协议的类:

@interface ConcreteStrategyA : NSObject <Strategy>
{
    // ivars for A
}
@end
Run Code Online (Sandbox Code Playgroud)

实现必须提供-execute方法(因为它被声明为@required):

@implementation ConcreteStrategyA

- (void) execute
{
    NSLog(@"Called ConcreteStrategyA execute method");
}

@end
Run Code Online (Sandbox Code Playgroud)

你可以做一个类似的ConcreteStrategyB课程,但我不打算在这里展示.

最后,创建一个具有维护当前策略的属性的上下文类.

@interface Context : NSObject
{
    id<Strategy> strategy;
}
@property (assign) id<Strategy> strategy;

- (void) execute;

@end
Run Code Online (Sandbox Code Playgroud)

这是实施.委托给策略-execute方法的方法恰好也被称为-execute,但不一定如此.

@implementation Context

@synthesize strategy;

- (void) execute
{
    [strategy execute];
}

@end
Run Code Online (Sandbox Code Playgroud)

现在我将制作一些实例并将它们用于:

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];    
Run Code Online (Sandbox Code Playgroud)

控制台输出显示策略已成功更改:

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
Run Code Online (Sandbox Code Playgroud)

请注意,如果协议未指定@required,则该方法是可选的.在这种情况下,上下文需要检查策略是否实现了该方法:

- (void) execute
{
    if ([strategy respondsToSelector:@selector(execute)])
        [strategy execute];
}
Run Code Online (Sandbox Code Playgroud)

这是一种常见的Cocoa模式,称为委托.有关Cocoa中的委派和其他设计模式的更多信息,请参阅此内容.

  • 而不是id <Strategy,NSObject>,通常最好使策略本身继承自<NSObject>协议:"@ protocol Protocol <NSObject>"这几乎总是你想要的,并简化了使用. (3认同)