带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(4)https://developer.aliyun.com/article/1338239?groupCode=taobaotech
状态的信息 StateInfo
包含的功能和特点:
- 当前上下文仅有一种状态信息流转
- 业务方可以保存多个状态键值对,状态根据需要执行相应的代码逻辑。
状态信息的声明和实现代码示例如下
@interface TBBaseStateInfo : NSObject { @private
TBBaseState<TBBaseStateDelegate> *_currentState; //记录当前的 State
}
//使用当前的 State 执行
- (void)performAction;
//更新当前的 State
- (void)setState:(TBBaseState <TBBaseStateDelegate> *)state;
//获取当前的 State
- (TBBaseState<TBBaseStateDelegate> *)getState;
@end
@implementation TBBaseStateInfo
- (void)performAction {
//当前状态开始执行
[_currentState perfromAction:self];
}
- (void)setState:(TBBaseState <TBBaseStateDelegate> *)state {
_currentState = state;
}
- (TBBaseState<TBBaseStateDelegate> *)getState { return _currentState;
}
@end
上层业务代码示例如下
typedef NS_ENUM(NSInteger, TBStateType) {
TBStateTypeNormal, //空状态
3TBStateTypeSingleCode, //单码展示态
TBStateTypeMultiCode, //多码展示态
};
@interface TBStateInfo : TBBaseStateInfo
//以 key-value 的方式存储业务 type 和对应的状态 state
- (void)setState:(TBBaseState<TBBaseStateDelegate> *)state forType:(TBStateType)type;
//更新 type,并执行 state
- (void)setType:(TBStateType)type; @end
@implementation TBStateInfo
- (void)setState:(TBBaseState<TBBaseStateDelegate> *)state forType:(TBStateType)type { [self.stateDict tb_setObject:state forKey:@(type)];
}
- (void)setType:(TBStateType)type { id oldState = [self getState];
//找到当前能响应的状态
id newState = [self.stateDict objectForKey:@(type)];
//如果状态未发生变更则忽略if (oldState == newState)
return;
if ([newState respondsToSelector:@selector(perfromAction:)]) { [self setState:newState];
//转态基于当前的状态信息开始执行[newState perfromAction:self];
}
}
@end
状态的基类 BaseState
包含的功能和特点:
- 定义了状态的基类
- 声明了状态的基类需要遵循的 Protocol
Protocol 如下,基类为空实现,子类继承后,实现对 StateInfo 的处理。
1 @protocol TBBaseStateDelegate <NSObject>
2 - (void)perfromAction:(TBBaseStateInfo *)stateInfo;
3 @end
上层(以单码 State 为例)代码示例如下
@interface TBSingleCodeState : TBBaseState
@end
@implementation TBSingleCodeState
//实现 Protocol
- (void)perfromAction:(TBStateInfo *)stateAction {
//业务逻辑处理 Start
...
//业务逻辑处理 End
}
@end
业务层调用
以下代码生成一系列状态,在合适时候进行状态的切换。
//状态初始化
- (void)setupState {
TBSingleCodeState *singleCodeState = TBSingleCodeState.new; //单码状态TBNormalState *normalState = TBNormalState.new; //正常状态TBMultiCodeState *multiCodeState = [self getMultiCodeState]; //多码状态
[self.stateInfo setState:normalState forType:TBStateTypeNormal]; [self.stateInfo setState:singleCodeState forType:TBStateTypeSingleCode];
[self.stateInfo setState:multiCodeState forType:TBStateTypeMultiCode];
)
//切换常规状态
- (void)processorA {
//...
[self.stateInfo setType:TBStateTypeNormal];
//...
}
//切换多码状态
- (void)processorB {
//...
22 | | [self.stateInfo setType:TBStateTypeMultiCode]; |
23 | | //... |
24 | } | |
25 | | |
26 | //切换单码状态 |
27 | - (void)processorC { |
28 | //... |
29 | [self.stateInfo setType:TBStateTypeSingleCode]; |
30 | //... |
31 | } |
最好根据状态机图编写状态切换代码,以保证每种状态都有对应的流转。
次态→ 初态↓ | 状态A | 状态B | 状态C |
状态A | 条件A | ... | ... |
状态B | ... | ... | ... |
状态C | ... | ... | ... |
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(6)https://developer.aliyun.com/article/1338218?groupCode=taobaotech