目标:在表单验证场景,对策略模式的一次实践
代码
基于Typescript,对于password这类需要验证长度范围的输入进行单独处理,将额外的判定条件利用strategyContext辅助方法进行转换,最终得到类型为(password: string) => boolean的函数体,保存在Validation类中的rules数组中。
// 验证密码的长度
type ValidPassword = {
minLength: number;
maxLength: number;
};
// 验证内容
interface ValidStrategyProps {
isValidPhone: (phone: string) => boolean;
isValidPassword: (password: string) => boolean;
}
// 验证方法
export const ValidStrategy = {
isValidPhone: (phone: string): boolean => /1\d{10}/.test(`${phone}`),
isValidPassword: (password: string): ((extra?: ValidPassword) => boolean) =>
(extra: ValidPassword = { minLength: 8, maxLength: 20 }) =>
password.length >= extra.minLength && password.length <= extra.maxLength,
};
// 将用户输入转化为函数形式,存放在Validation-rules中
const strategyContext = (rule: keyof ValidStrategyProps, toValidEle: string, extra?: ValidPassword):
(() => boolean) => {
if (rule === 'isValidPassword') {
const fn = ValidStrategy[rule](toValidEle);
return () => fn(extra);
}
return () => ValidStrategy[rule](toValidEle);
};
// 验证类,保存验证方法
export default class Validation {
rules: (() => boolean)[];
constructor() {
this.rules = [];
}
add(rule: keyof ValidStrategyProps, toValidEle: string): void {
this.rules.push(strategyContext(rule, toValidEle));
}
valid(): boolean {
return this.rules.every(rule => rule());
}
}
使用
const validationIns = new Validation();
validationIns.add('isValidPhone', 1234567890);
validationIns.add('isValidPassword', 010101010101);
const isValid = validationIns.valid();