背景
假设我们正在编写一个注册页面,在点击注册按钮之时,有下面三条校验逻辑:
- 用户名不能为空
- 密码长度不能少于6位
- 手机号码必须符合格式
常规写法:
const form =document.getElementById("registerForm");
form.onsubmit=function(){
if(form.userName.value === ""){
alert("用户名不能位空");
return false;
}
if(form.password.value.length<6){
alert("密码长度不能少于6位");
return false;
}
if(!/^1[3|5|8][0-9]{9}$/.test(form.phoneNumber.value)){
alert("手机号码格式不正确");
return false;
}
...
}
复制代码
策略模式介绍
- 策略模式是一种行为涉及模式,他能让你定义一系列算法,把他们一个个封装起来,并使它们可以相互替换。
- 策略模式让你能将各种算法的代码、内部数据和依赖关系与其他代码隔离开来。不同客户端可通过一个简单接口执行算法,并能在运行时进行切换。
策略模式的组成
- 一个策略模式至少由两部分组成。
第一部分是一组策略类,策略类封装了具体的算法,并负责具体的计算过程。
第二个部分是环境类context,context接受客户的请求,随后把请求委托给某一个策略类。
利用策略模式改写:
定义策略规则,封装表单校验逻辑:
const strategies={
isNonEmpty:function(value,errMsg){
if(value === ''){
return errMsg;
}
},
minLength:function(value,length,errMsg){
if(value.length<length){
return errMsg;
}
},
isMobile:function(value,errMsg){
if(!/^1[3|5|8][0-9]$/.test(value)){
return errMsg;
}
}
}
复制代码
定义环境类context,进行表单校验,调用策略:
form.onsubmit=function(){
const validator=new Validator();
validator.add(form.userName,'isNonEmpty','用户名不能为空');
validator.add(form.password,'minLength:6','密码长度不能少于6位');
validator.add(form.phoneNumber,'isMobile','手机号码格式不正确');
const errMsg=validator.start();
if(errMsg){
alert(errMsg);
return false;
}
}
复制代码
Validator类代码如下:
class Validator{
constructor(){
this.cache=[];
}
add(dom,rule,errMsg){
const arr=rule.split(":");
this.cache.push(()=>{
const strategy=arr.shift();
arr.unshift(dom.value);
arr.push(errMsg);
return strategies[strategy].apply(dom,arr);
})
}
start(){
for(let i=0;i<this.cache.length;i++){
const msg=this.cache[i]();
if(msg) return msg;
}
}
}
复制代码
策略模式的优缺点:
优点:
- 可以有效地避免多重条件选择语句。
- 对
开放-封闭原则
完美支持,将算法封装在独立的 strategy 中,使得它们易于切换,易于理解,易于扩展。 - 可以使算法复用在系统的其他地方,避免许多重复的复制粘贴工作。
缺点:
- 使用策略模式会在程序中增加许多策略类或策略对象
- 要使用策略模式,必须了解所有的 strategy,了解它们的不同点,我们才能选择一个合适的 strategy。这是违反
最少知识原则
的。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END