我正在实现一个状态管理器来控制对象状态模式。我的StateManager
有一个属性currentMode
,可以是PenState
,EraserState
,ZoomState
类型(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
答案 0 :(得分:4)
状态模式的要点是状态应该从状态机的角度来看是可以互换的,所以每个状态应该符合一个协议(或者在你的情况下,一个超类应该提供公共接口)所有常见要求。因此,您的所有状态(您的工具)都应接受使用指定大小的大小和操作,设置笔的大小和绘制线条,或设置缩放大小和执行缩放。
如果状态存在差异,您可以进行类检查,这应该是相对不常见的,并且在相对特定的代码中。如果代码是特定的,那么你通常应该知道预期的类,这样你就可以进行类型转换。
继承和协议也可用于创建状态的子集,因此您可以拥有工具状态(具有大小),但也可以绘制状态(使用颜色),然后您可以继续类型转换为超类/ protocol而不关心每个特定的实现类。