feature: design patter

This commit is contained in:
binpeng.liu
2023-10-31 15:17:07 +08:00
parent 4b8c957341
commit 32eda66409
29 changed files with 3809 additions and 16 deletions

View File

@@ -1,19 +1,21 @@
## 妙用设计模式来设计一个客户端校验器
> 订单在提交的时候会面临不同的校验规则,不同的校验规则会有不同的处理。假设这个处理就是弹窗。
>
> 有的时候会命中规则1则弹窗1有的时候同时命中规则1、2、3但由于存在规则的优先级则会处理优先级最高的弹窗1。
>
> 老的业务背景下,弹窗优先级或者说校验规则是统一的。直接用函数翻译实现,写多个 if 问题不大。
>
> 但在新业务背景下,不同的条件,弹窗优先级不一致,之前的写法需要写大量的嵌套判断,代码难以维护。
>
> 所以问题抽象为:如何设计一个校验器
> 业务逻辑千变万化,弹窗优先级不断改变,代码冗余问题和难以维护问题如何解决?
> 本篇文章从设计模式角度出发讨论责任链设计模式和工厂设计模式2个方式如何去设计一个校验器同时解决代码冗余和难以维护的问题
## 问题背景
订单在提交的时候会面临不同的校验规则,不同的校验规则会有不同的处理。假设这个处理就是弹窗。
有的时候会命中规则1则弹窗1有的时候同时命中规则1、2、3但由于存在规则的优先级则会处理优先级最高的弹窗1。
老的业务背景下,弹窗优先级或者说校验规则是统一的。直接用函数翻译实现,写多个 if 问题不大。
但在新业务背景下,不同的条件,弹窗优先级不一致,之前的写法需要写大量的嵌套判断,代码难以维护。
所以问题抽象为:如何设计一个校验器
为了清晰说明问题假设线上的弹窗校验规则为A -> B -> C
```Plain
@@ -193,7 +195,7 @@ Node 洋葱模式:发送一个 Request 一层层中间件去处理,比如添
采用责任链设计模式。基类 `OrderSubmitBaseValidator` 声明接口,是一个抽象类:
- 有一个属性 `nextValidator` 用于指向下一个校验器
- 有一个方法 `- (void)validate:(id)params;` 用于处理校验,内部默认实现是传递给下一个校验器
- 有一个方法 `- (void)validate:(id)params;` 用于处理校验,内部利用模版模式,默认实现是传递给下一个校验器
```Shell
//.h
@@ -294,7 +296,7 @@ let validateType = [OrderSubmitValidator generateTypeWithParams:params];
[OrderSubmitValidator validateWith:validateType];
```
`validateWith` 方法内部根据 validateType 去组装 Map 的 key然后从 Map 中取出具体规则组合,然后依次迭代遍历执行
利用策略模式 `validateWith` 方法内部根据 validateType 去组装 Map 的 key然后从 Map 中取出具体规则组合,然后依次迭代遍历执行
```
let rulesMap = {
@@ -303,13 +305,16 @@ let rulesMap = {
!isVIP: [a-c-d-b],
}
```
这部分策略的生成也可以单独抽取出去,比如 ValidateStrategyFactory 去根据不同的信息,生成不同的策略。
优点:
1. 解决了现在的错误弹窗的隐含逻辑,后续人接手,弹窗优先级清晰可见,提高可维护性,减少出错概率
2. 对于判断(校验)的增减都无需关心其他的校验规则。类似维护链表,仅在一开始指定即可,符合“开闭原则
2. 对于判断(校验)的增减都无需关心其他的校验规则。类似维护链表,仅在一开始指定即可,符合“开闭原则
3. 对于现有校验规则的修改足够收口,每个规则都有自己的 validator 和 validate 方法
4. 目前弹窗优先级针对 EVA 、BTC 存在不同优先级顺序,如果按照现有的方案实施,则会存在很多冗余代码
4. 目前弹窗优先级针对 isVIP、isCharged 存在不同优先级顺序,如果按照现有的方案实施,则会存在很多冗余代码
5. 按照策略模式,不同的校验规则,组装不同的策略,也可以单独抽取出去,独立维护,更清晰
6. validate 内部按照模版模式,调用 `isValidate` 方法,每个单独的 Validator 不需要额外去调用 next设计更加健壮防止别人漏写
@@ -396,5 +401,5 @@ OrderSumitValidatorFactory {
- 优先级的关系维护在不同的子类中,各司其职,独立维护
最后选什么?组合优于继承,个人倾向使用责任链模式去组织代码。关于责任链设计模式的文章也可以看这篇[文章](./../Chapter6%20-%20Design%20Pattern/6.23.md)
最后选什么?组合优于继承,个人倾向使用责任链模式去组织代码。

View File

@@ -32,8 +32,12 @@
```
### 类别的作用
拓展当前类,为类添加方法
可以把类的实现分开在几个不同的源文件里,所以好处是:
- 减少耽搁文件的代码行数
- 可以把不痛的功能组织到不同的 category 里
- 可以由多个开发者共同完成一个大的类,方便协作
- 拓展当前类,为类添加方法
- 声明私有方法
### 类别的局限性