带你读《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