策略模式
策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。
将不变的部分和变化的部分隔开是每个设计模式的主题,策略模式也不例外,策略模式的目的就是将算法的使用与算法的实现分离开来。
一个基于策略模式的程序至少由两部分组成。第一个部分是一组策略类,策略类封装了具体 的算法,并负责具体的计算过程。
第二个部分是环境类Context,Context 接受客户的请求,随后 把请求委托给某一个策略类。要做到这点,说明Context中要维持对某个策略对象的引用。
实例阶段1
分moduleType
将获取到的数据保存在model
的namespace
中。
以下是最开始的写法,很单纯的写法switch case
.
可以看出,其中存在大量的重复代码,只是每次传送的data
不同罢了。
所以我们可以思考将其提出来,使代码更简洁,更具有可扩展性和移植性
。
switch (moduleType) {
case MODULETYPE.EXPOSURE_MANAGEMEN.key:
yield put({
type: 'save',
payload: {
exposureData: {
list: rows,
pagination,
},
},
})
break;
case MODULETYPE.POLICY_NORMS.key:
yield put({
type: 'save',
payload: {
policyData: {
list: rows,
pagination,
},
}
})
break;
case MODULETYPE.CONSUMPTION_WARNING.key:
yield put({
type: 'save',
payload: {
cautionData: {
list: rows,
pagination,
},
}
})
break;
default:
break;
}
实例阶段2
将save
函数提取了出来,统一发送请求,而不必在switch
中多次撰写。
但是仍然存在问题,switch
中的数据处理还是存在重复的部分。
所以需要在做打算,这时阶段3的策略模式
上场了。
let newPayload={};
switch (moduleType) {
case MODULETYPE.EXPOSURE_MANAGEMEN.key:
newPayload = {
exposureData: {
list: rows,
pagination,
},
}
break;
case MODULETYPE.POLICY_NORMS.key:
newPayload = {
policyData: {
list: rows,
pagination,
},
}
break;
case MODULETYPE.CONSUMPTION_WARNING.key:
newPayload = {
cautionData: {
list: rows,
pagination,
},
}
break;
default:
break;
}
yield put({
type: 'save',
payload: {
...newPayload,
}
})
实例阶段3
全局中已经存储了moduleType
,只需要提前定义一个tmpPayload
,将得到的data
存在对应模块中。
再执行save
的时候,payload
自然就是需要的模块中的data
。
const tmpPayload = {
"exposure": {},
"policy": {},
"caution": {},
};
tmpPayload[moduleType] = {
list: rows,
pagination,
};
const articleList = tmpPayload[moduleType];
yield put({
type: 'save',
payload: {
articleList,
}
})
总结
由以上情况可以看出,代码量逐渐变少,而且思路也逐渐地清晰了。
代码设计的思路,书上学不到这些东西,所以需要多多应用,思考。
代码重构,如何能够得到更好的效果。
如上面的例子所示:如果是阶段1,下次新增一个模块的话,又得重新写一个case情况,而唯一的不同就是里面的data不同,但是却不得不多写很多代码,这就是弊端。
所以,阶段3和阶段1的对比一目了然。
- 代码更简洁
- 可移植性更高
- 下次新增一个
moduleType
只需要添加一个moduleType
的定义即可,无需在switch case
中再重新很多重复代码