策略模式
策略模式定义了一系列算法,并将每种算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。
策略模式优化if else
- 策略模式可以用来代替多重if else语句。
Vue中使用策略模式
我们以一个表单验证的例子来看看如何使用策略模式优化if else。
methods: {
validateForm() {
if(this.type === 'register') {
// do register validation
} else if(this.type === 'login') {
// do login validation
} else if(this.type === 'forget') {
// do forget validation
}
}
}
这些校验规则可以抽取成策略对象:
const strategies = {
register: function() {
// do register validation
},
login: function() {
// do login validation
},
forget: function() {
// do forget validation
}
}
然后在validateForm中使用策略对象:
methods: {
validateForm() {
const strategy = strategies[this.type]
strategy()
}
}
这样就替换掉了冗长的if else链。
策略模式的优点
- 去除复杂的if else逻辑
// 策略对象
const strategies = {
A() { //... },
B() { //... }
}
methods: {
// 直接使用策略对象,避免条件判断
// 如不使用则存在大量if else判断
doSomething() {
strategies[this.type]()
}
}
- 扩展性好,新增策略容易
- 不同策略可以独立变化,不影响客户端
- 遵循开闭原则(新增策略时无需修改原代码)
// 新增策略
strategies.C = () => {
// 新策略C实现
}
// 客户端代码不需要修改,开闭原则
doSomething() {
strategies[this.type]()
}
拓展
我们可以将策略对象抽取为模块,在运行时动态加载,实现运行时策略扩展。
也可以用Composition API进一步封装策略模块。
import registerValidator from './registerValidator'
import loginValidator from './loginValidator'
export default {
setup() {
return {
validators: {
register: registerValidator,
login: loginValidator
}
}
}
}
这样策略模式就可以大大优化if else逻辑,提升代码扩展性。
策略模式的应用场景
-
不同的缓存策略
可以定义内存缓存、本地存储缓存、请求缓存等不同策略,根据需要动态切换。 -
多种排序算法
封装冒泡排序、快速排序、归并排序等算法为策略,客户端代码不变就可以切换不同的排序方式。 -
不同的网络请求方案
封装 Ajax 请求、Fetch API、WebSocket等为策略对象,实现可拔插的网络请求方式。 -
不同的日志记录方式
文件日志、控制台日志、远程日志等可以抽象成策略来互换。 -
不同的加密/解密算法
对称加密、非对称加密、哈希算法等可以封装成策略对象。 -
不同的支付方式
微信支付、支付宝、银联等支付可以抽象成策略类。 -
平台适配层
抽取不同平台的适配策略,如 iOS 策略、Android 策略、Web 策略等。 -
国际化
封装中英文策略等,运行时动态加载所需的语言包。