设计模式之策略模式
web前端开发
共 3392字,需浏览 7分钟
· 2021-03-29
作者 | 汤姆大叔
介绍
正文
validator = {
validate: function (value, type) {
switch (type) {
case 'isNonEmpty ':
{
return true; // NonEmpty 验证结果
}
case 'isNumber ':
{
return true; // Number 验证结果
break;
}
case 'isAlphaNum ':
{
return true; // AlphaNum 验证结果
}
default:
{
return true;
}
}
}
};
// 测试
alert(validator.validate("123", "isNonEmpty"));
那如何来避免上述代码中的问题呢,根据策略模式,我们可以将相同的工作代码单独封装成不同的类,然后通过统一的策略处理类来处理,OK,我们先来定义策略处理类,代码如下:
var validator = {
// 所有可以的验证规则处理类存放的地方,后面会单独定义
types: {},
// 验证类型所对应的错误消息
messages: [],
// 当然需要使用的验证类型
config: {},
// 暴露的公开验证方法
// 传入的参数是 key => value对
validate: function (data) {
var i, msg, type, checker, result_ok;
// 清空所有的错误信息
this.messages = [];
for (i in data) {
if (data.hasOwnProperty(i)) {
type = this.config[i]; // 根据key查询是否有存在的验证规则
checker = this.types[type]; // 获取验证规则的验证类
if (!type) {
continue; // 如果验证规则不存在,则不处理
}
if (!checker) { // 如果验证规则类不存在,抛出异常
throw {
name: "ValidationError",
message: "No handler to validate type " + type
};
}
result_ok = checker.validate(data[i]); // 使用查到到的单个验证类进行验证
if (!result_ok) {
msg = "Invalid value for *" + i + "*, " + checker.instructions;
this.messages.push(msg);
}
}
}
return this.hasErrors();
},
// helper
hasErrors: function () {
return this.messages.length !== 0;
}
};
然后剩下的工作,就是定义types里存放的各种验证类了,我们这里只举几个例子:
// 验证给定的值是否不为空
validator.types.isNonEmpty = {
validate: function (value) {
return value !== "";
},
instructions: "传入的值不能为空"
};
// 验证给定的值是否是数字
validator.types.isNumber = {
validate: function (value) {
return !isNaN(value);
},
instructions: "传入的值只能是合法的数字,例如:1, 3.14 or 2010"
};
// 验证给定的值是否只是字母或数字
validator.types.isAlphaNum = {
validate: function (value) {
return !/[^a-z0-9]/i.test(value);
},
instructions: "传入的值只能保护字母和数字,不能包含特殊字符"
};
使用的时候,我们首先要定义需要验证的数据集合,然后还需要定义每种数据需要验证的规则类型,代码如下:
var data = {
first_name: "Tom",
last_name: "Xu",
age: "unknown",
username: "TomXu"
};
validator.config = {
first_name: 'isNonEmpty',
age: 'isNumber',
username: 'isAlphaNum'
};
最后,获取验证结果的代码就简单了:
validator.validate(data);
if (validator.hasErrors()) {
console.log(validator.messages.join("\n"));
}
总结
策略模式定义了一系列算法,从概念上来说,所有的这些算法都是做相同的事情,只是实现不同,他可以以相同的方式调用所有的方法,减少了各种算法类与使用算法类之间的耦合。
从另外一个层面上来说,单独定义算法类,也方便了单元测试,因为可以通过自己的算法进行单独测试。
实践中,不仅可以封装算法,也可以用来封装几乎任何类型的规则,是要在分析过程中需要在不同时间应用不同的业务规则,就可以考虑是要策略模式来处理各种变化。
本文完〜
推荐阅读
学习更多技能
请点击下方web前端开发
评论
微服务与领域驱动设计,架构实践总结
来源:知了一笑👉 欢迎加入小哈的星球 ,你将获得: 专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡 / 赠书福利全栈前后端分离博客项目 2.0 版本完结啦, 演示链接:http://116.62.199.48/ ,新
小哈学Java
0
面试官:电商库存扣减如何设计?如何防止超卖?
来源:my.oschina.net/xiaolyuh/blog/1615639👉 欢迎加入小哈的星球 ,你将获得: 专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡 / 赠书福利全栈前后端分离博客项目 2.0 版本完结啦, 演示
小哈学Java
0
实现订单30分钟自动取消的策略
原文:juejin.cn/post/7285167401821798400简介在电商和其他涉及到在线支付的应用中,通常需要实现一个功能:如果用户在生成订单后的一定时间内未完成支付,系统将自动取消该订单。本文将详细介绍基于Spring Boot框架实现订单30分钟内未支付自动取消的几种方案,并提供实例
JAVA乐园
0
即将登陆,Win11的新功能:手机当摄像头、省电模式升级
近日,微软为其Windows 11操作系统推出了一次相对较小的功能更新“Moment 5”,但更多的激动人心的变化将在2024年下半年随着24H2版本的发布而揭晓。尽管完整的更新列表尚未公布,但一系列即将加入的新功能已经引起了广泛关注。引人注目的功能之一是,Windows 11将支持将手机作为无线网
Python 知识大全
3
公司新来一个同事,把风控系统设计得炉火纯青,万能通用,稳的一批!
点击关注公众号,Java 干货及时推送↓推荐阅读:铜三铁四,怒拿 35K * 14 薪!作者:wingli链接:https://juejin.cn/post/7182774381448282172一、背景1.为什么要做风控? 这不得拜产品大佬所赐目前我们业务有使用到非常多的AI能力,如oc
Java技术栈
0
带你玩转Linux系统之lscpu命令
链接:https://bbs.huaweicloud.com/blogs/422603一、lscpu命令介绍lscpu 是一个 Linux 命令,用于显示CPU架构的详细信息。它可以用来查看 CPU 的型号、主频、架构、虚拟化支持等。二、lscpu命令的使用帮助2.1 命令格式lscpu [选项]2
良许Linux
0
C语言基础之动态内存操作汇总
来源:机器之心1、堆区空间申请#include <stdlib.h> //头文件void *malloc(size_t size);//函数size表示申请的空间字节数函数的返回值:成功:返回值空间起始地址失败:NULL特点:分配指定大小的内存空间;分配的内存空间是连续的;需要手动释放
良许Linux
0
大模型并行训练指南:通俗理解Megatron-DeepSpeed之模型并行与数据并行(下)
文末《大模型项目开发线上营》秒杀倒计时↓↓↓接前文:(上)篇>>>大模型并行训练指南:通俗理解Megatron-DeepSpeed之模型并行与数据并行(上)(中)篇>>>大模型并行训练指南:通俗理解Megatron-DeepSpeed之模型并行与数据并行(中)06
七月在线实验室
10