2010-10-26 76 views
4

我理解“策略模式”的概念,但我仍然有点困惑。我们有一个类DogDog具有MovementBehaviour(接口),其可以是MovementBehaviourNormalMovementBehaviourFastMovementBehaviourNormalMovementBehaviourFast都包含名为move的方法。目标C - 战略模式?

问题:访问move方法的狗属性的最佳方法是什么? 将dog对象作为代表传递给MovementBehaviour是不是一个好主意?

回答

6

通常,您不应该直接从策略对象访问Dog上的属性。相反,你可以做的是提供一个移动方法,根据旧的位置返回一个新的位置。因此,举例来说,如果您有:

@interface Dog : NSObject { 
    NSInteger position; 
    DogStrategy * strategy; 
} 
@property(nonatomic, assign) NSInteger position; 
@property(nonatomic, retain) DogStrategy * strategy; 
- (void)updatePosition; 
@end 

@implementation Dog 
@synthesize position, strategy; 

- (void)updatePosition { 
    self.position = [self.strategy getNewPositionFromPosition:self.position]; 
} 
@end
@interface DogStrategy : NSObject { } 
- (NSInteger)getNewPositionFromPosition:(NSInteger)pos; 
@end 

// some parts elided for brevity 

@interface NormalDogStrategy : DogStrategy { } 
@end 

@implementation NormalDogStrategy 
- (NSInteger)getNewPositionFromPosition:(NSInteger)pos { 
    return pos + 2; 
} 
@end

然后,当你实例化一个狗,你可以为它分配NormalDogStrategy并调用[dog updatePosition] - 狗会要求其策略的更新后的位置,并指派对其实例变量本身。您已经避免将Dog的内部暴露给您的DogStrategy,并且仍然完成了您的预期。

+0

非常感谢,很棒的细节。 NormalDogStrategy不应该继承DogStrategy,而应该将其用作接口:NormalDogStrategy 。纠正我,如果我错了 – aryaxt 2010-10-26 04:21:50

+0

而DogStrategy应该是一个协议,而不是实际的类? – aryaxt 2010-10-26 04:23:56

+0

如果您使用的是实际的战略模式,那么不会 - 因为NormalDogStrategy是一种* DogStrategy,不是一个填充DogStrategy合同的对象,也不是其他的东西。如果你使DogStrategy成为一个协议,那么它将遵循使NormalDogStrategy成为一个协议,并且你不能这么做,因为你必须在NormalDogStrategy中实现方法。 (这是抽象类会来在ObjC得心应手,但我们已经到了活不下去。) – Tim 2010-10-26 04:33:29