JavaScript设计模式之策略模式【组合委托】
前言:语言只是工具,思想才是核心
今天要总结的是 策略模式
策略在开发中的应用非常广泛,所以也是非常常见且使用的设计模式。
在实际开发中,往往在实现一个功能时,有多种解决方案可行。
常见场景:
- 解压:gzip算法解压,gzip算法解压
- 表单验证:手机号验证,邮箱验证,密码格式验证
- 工资计算:技术猛男工资,鼓励师妹妹工资,冷血产品经理工资
总结策略模式的使用场景,在想实现某个效果时,有多种不同的达成方式。这个时候就要考虑策略模式(如果你写了很多ifelse)
使用策略模式的优点:
- 1.使代码更加清晰可读,减少繁多的if-else
- 2.功能更易拓展,可维护,健壮性【单一指责,抽离变与不变。如果你看了上篇单例设计模式你就看到我也强调过这一点】
- 3.策略可重用
策略模式的应用场景:
场景一:
工资计算
财务妹妹想要给技术猛男、鼓励师妹妹、冷血产品经理来统计他们本月的工资。但他们的工资计算方式不一样呀,这可咋整?
- 技术猛男:(10000基本+1000项目奖励)* 1.2绩效
- 鼓励师妹妹:(9000基本)*1绩效
- 冷血产品经理:(500基本)*1.5绩效
- 【绩效每月都不同】
本着抽离变与不变的思路:
- 变:不同角色不同计算方式
- 不变:都需要计算工资
面对对象思路的写法:
<script>
// 策略类 定义各个角色的工资计算方式
function WageStrategy() {
}
WageStrategy.prototype.ROLE = {
IT: 'itHandsomeBoy',
ENCOURAGE: 'encourager',
MANAGER: 'productManager',
};
WageStrategy.prototype.itHandsomeBoy = function (performance) {
return (10000 + 2000) * performance;
}
WageStrategy.prototype.encourager = function (performance) {
return (9000) * performance;
}
WageStrategy.prototype.productManager = function (performance) {
return (500) * performance;
}
WageStrategy.prototype.getRoleWage = function (role, performance) {
return this[role](performance);
}
// 中间类 (发起计算的财务)【持有策略对象】
function FinancialMan(strategy) {
this.strategy = strategy;
}
FinancialMan.prototype.getWage = function (role, performance) {
return this.strategy.getRoleWage(role, performance);
};
// 运行
let financialMan = new FinancialMan(new WageStrategy());
console.log(financialMan.getWage(financialMan.strategy.ROLE.IT, 1.2));
console.log(financialMan.getWage(financialMan.strategy.ROLE.ENCOURAGE, 1));
console.log(financialMan.getWage(financialMan.strategy.ROLE.MANAGER, 1.5));
</script>
上面是模拟像Java这样基于类的语言,而js中存在很多不一样的特性,例如:函数即对象!所以以下是改进的
Js版本的策略模式。
<script>
// 策略对象,封装工资算法
let wageStrategy = {
ROLE : {
IT : 'itHansomeBoy',
ENCOURAGE : 'encourager',
MANAGER : 'productManager',
},
itHansomeBoy: function (performance) {
return (10000 + 2000) * performance;
},
encourager: function (performance) {
return (9000) * performance;
},
productManager: function (performance) {
return (500) * performance;
},
};
// 计算工资对象
let getWage= function (role, performance) {
return wageStrategy[role](performance);
}
console.log(getWage(wageStrategy.ROLE.IT, 1.2)); // 14400
console.log(getWage(wageStrategy.ROLE.ENCOURAGE, 1)); // 9000
console.log(getWage(wageStrategy.ROLE.MANAGER, 1.5)); // 750
</script>
场景二:
表单验证(注册账号)
用户在填完一堆信息后【如:手机号、邮箱号、姓名、密码、验证码】,点击注册,此时应该先对每个字段进行检查,都通过后才能提交到后台。
比较猛的写法:
let register = function () {
let name, phone,
if(!name) {
return;
}else if (!phone || phone.length !== 11) {
return;
}
// do register request
}
随着需要检验的字段越来越多,那么else if的逻辑越来越重。并且,如果有个完善信息页面,同样需要用到手机号,邮箱号这些信息检测怎么复用勒?
那么,策略模式来了:
<script>
// 表单检验策略类
let checkInfoStrategy = {
phone: function (phone) {
let pass = true;
let tips = '';
if (!phone) {
pass = false;
tips = '手机号不能为空';
}
return { pass, tips };
},
email: function (email) {
let pass = true;
let tips = '';
if (!email) {
pass = false;
tips = '邮箱不能为空';
} else if (email.indexOf('@') < 0) {
pass = false;
tips = '邮箱格式不正确';
}
return { pass, tips };
}
}
// 中间者 发起表单检验
let Checker = function () {
this.cache = []; // 存放需要检验项:{策略,待检验字符}
// 添加待检查项
this.add = function (stragetyItem, beCheckInfo) {
this.cache.push({ item: stragetyItem, info: beCheckInfo });
return this;
};
// 开始检查
this.startCheck = function () {
let result = { pass : true, tips : '' };
for (let i = 0; i < this.cache.length; i++) {
let checkItem = this.cache[i];
let {pass, tips} = checkItem.item(checkItem.info);
result.pass = pass;
result.tips = tips;
if (!pass) {
break;
}
}
return result;
};
}
// 执行
let phone = '18826274139';
let email = '';
let checker = new Checker();
checker.add(checkInfoStrategy.phone, phone).add(checkInfoStrategy.email, email);
let { pass, tips } = checker.startCheck();
console.log(':::' + pass, tips); // :::false 邮箱格式不正确
</script>
其他不多说了,一定要动过。
思路就是抽离变与不变。策略类之放不同的算法/逻辑,使用中间类来协助发起策略类的使用。
JavaScript设计模式之策略模式【组合委托】的更多相关文章
- JavaScript设计模式(策略模式)
策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换.将不变的部分和变化的部分隔开是每个设计模式的主题,策略模式也不例外,策略模式的目的就是将算法的使用与算法的实现分离开来 ...
- JavaScript设计模式之策略模式(学习笔记)
在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选 ...
- JavaScript设计模式之策略模式
所谓"条条道路通罗马",在现实中,为达到某种目的往往不是只有一种方法.比如挣钱养家:可以做点小生意,可以打分工,甚至还可以是偷.抢.赌等等各种手段.在程序语言设计中,也会遇到这种类 ...
- 第二章 --- 关于Javascript 设计模式 之 策略模式
这一章节里面,我们会主要的针对JavaScript中的策略模式进行理解和学习 一.定义 策略模式: 定义一系列的算法,把他们封装起来,并且是他们可以相互替换. (这样的大的定义纲领,真的不好理解,特别 ...
- javascript设计模式:策略模式
前言 策略模式有效利用组合.委托.多态等技术和思想,可以有效避免多重条件选择语句. 策略模式对开放-封闭原则提供了很好的支持,将算法封装在strategy中,使得他们易于切换.理解.扩展. 策略模式中 ...
- Head First 设计模式--1策略模式 组合优于继承
策略模式:第一了算法族,分别封装起来,让他们之间可以互相替换,次模式让算法的变化独立于使用算法的客户. 首先看个错误的面向对象. 假如我们需要写一个关于鸭子的程序,各种类型的鸭子.第一想到的就是建一个 ...
- 再起航,我的学习笔记之JavaScript设计模式20(策略模式)
策略模式 策略模式(Strategy):将定义的一组算法封装起来,使其相互之间可以替换.封装的算法具有一定的独立性,不会随客户端变化而变化. 其实策略模式在我们生活中可应用的地方还是比较多的,比如在商 ...
- JavaScript设计模式_02_策略模式
在程序设计中,我们常常遇到这种情况,要实现某一个功能我们有很多种算法可以实现.这些算法灵活多样,而且可以随意互相替换.这种解决方案就是所谓的策略模式. /* * pre:策略模式 * 示例:公司计算奖 ...
- 理解javascript中的策略模式
理解javascript中的策略模式 策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. 使用策略模式的优点如下: 优点:1. 策略模式利用组合,委托等技术和思想,有效 ...
随机推荐
- 附002.Nginx全系列大总结
Nginx全系列总结如下,后期不定期更新. 欢迎基于学习.交流目的的转载和分享,禁止任何商业盗用,同时希望能带上原文出处,尊重ITer的成果,也是尊重知识. 若发现任何错误或纰漏,留言反馈或右侧添加本 ...
- Mysql的复制原理以及流程
MySQL复制概述 简单来说就是保证主服务器(Master)和从服务器(Slave)的数据是一致性的,向Master插入数据后,Slave会自动从Master把修改的数据同步过来(有一定的延迟),通过 ...
- Squeeze-and-Excitation Networks(SENet)详解
一.SENet简介 Squeeze-and-Excitation Networks(SENet)是由自动驾驶公司Momenta在2017年公布的一种全新的图像识别结构,它通过对特征通道间的相关性进行建 ...
- RecyclerView设置空视图
RecyclerView貌似不能直接设置空视图,所以可以自定义一个RecyclerView继承自RecyclerView并设置一个数据监听者监视数据状态. MyCyclerView.java pack ...
- MyBatis--动态插入多条数据
MySQL支持的一种插入多行数据的INSERT语句写法是 INSERT INTO 表名 (字段名1,字段名2,字段名3) VALUES (值1,值2,值3,...),(值1,值2,值3,...)... ...
- MySQL乱码问题(为什么?追根溯源)
引言 定位:查询数据库得到的结果集乱码,client端向数据库插入数据乱码. 网上有不少帖子,手把手地教给我们如何去改这一问题.方案大多数如下: 方案中最多介绍的就是更改配置文件,win下my.ini ...
- 对于Javaweb初学者的一些坑。#Javaweb
1.在配置好Tomcat之后 ,编译阶段发现报错 这种对于我个人来说一般有两种情况: ①在编写代码时(比如servlet)发现爆红,一般是maven的依赖没有导入,这个时候在xml文件中导入需要的包的 ...
- 2020牛客暑期多校训练营 第二场 B Boundary 计算几何 圆 已知三点求圆心
LINK:Boundary 计算几何确实是弱项 因为好多东西都不太会求 没有到很精通的地步. 做法很多,先说官方题解 其实就是枚举一个点 P 然后可以发现 再枚举一个点 然后再判断有多少个点在圆上显然 ...
- spring中IOC入口与加载步骤
ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring-context.xml&q ...
- 属性集 Properties
5.1 概述 java.util.Properties 继承于 Hashtable ,来表示一个持久的属性集.它使用键值结构存储数据,每个键及其对应值都是一个字符串.该类也被许多Java类使用,比如获 ...