如何在状态设计模式中避免类型转换或对象类检查?

时间:2015-01-03 10:48:05

标签: objective-c design-patterns state

我正在实现一个状态管理器来控制对象状态模式。我的StateManager有一个属性currentMode,可以是PenStateEraserStateZoomState类型(State的所有子类)。

但是,在获取currentMode时接收方,如何避免类型转换?设计有什么问题?什么是正确的方法呢?

State *state = [StateManager sharedManager].currentMode;
if([state isKindOfClass:[PenState Class]]) //how to avoid this type checking
{
    penState *penState = (PenState*)state;
    CGSize penSize = penState.size;
}

我的班级

@interface PenState : State

@property(nonatomic,strong) NSString *color;
@property(nonatomic,assign) CGSize size;

@end

@interface StateManager : NSObject
{

}
@property(nonatomic,strong)State *currentMode;

@end

更新

我是否需要在状态类中维护枚举

    typedef NS_ENUM(NSInteger, Mode)
    {
        None = 0,
        Pen,
        Eraser,
        Zoom
    };

@protocol StateProtocol <NSObject>
-(Mode)toolbarMode;
@end

@implementation WriteState

-(Mode)toolbarMode
{
    return Pen;
}

@end

1 个答案:

答案 0 :(得分:4)

状态模式的要点是状态应该从状态机的角度来看是可以互换的,所以每个状态应该符合一个协议(或者在你的情况下,一个超类应该提供公共接口)所有常见要求。因此,您的所有状态(您的工具)都应接受使用指定大小的大小和操作,设置笔的大小和绘制线条,或设置缩放大小和执行缩放。

如果状态存在差异,您可以进行类检查,这应该是相对不常见的,并且在相对特定的代码中。如果代码是特定的,那么你通常应该知道预期的类,这样你就可以进行类型转换。

继承和协议也可用于创建状态的子集,因此您可以拥有工具状态(具有大小),但也可以绘制状态(使用颜色),然后您可以继续类型转换为超类/ protocol而不关心每个特定的实现类。