本网站(662p.com)打包出售,且带程序代码数据,662p.com域名,程序内核采用TP框架开发,需要联系扣扣:2360248666 /wx:lianweikj
精品域名一口价出售:1y1m.com(350元) ,6b7b.com(400元) , 5k5j.com(380元) , yayj.com(1800元), jiongzhun.com(1000元) , niuzen.com(2800元) , zennei.com(5000元)
需要联系扣扣:2360248666 /wx:lianweikj
JavaScript设计模式之策略模式
iamitnan · 324浏览 · 发布于2020-08-18 +关注

前言:语言只是工具,思想才是核心

今天要总结的是 策略模式
策略在开发中的应用非常广泛,所以也是非常常见且使用的设计模式。
在实际开发中,往往在实现一个功能时,有多种解决方案可行。

常见场景:

  • 解压: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>

其他不多说了,一定要动过。
思路就是抽离变与不变。策略类之放不同的算法/逻辑,使用中间类来协助发起策略类的使用。

相关推荐

RN开发环境的npm私库本地debug调试

manongba · 698浏览 · 2019-05-09 17:03:46
你不知道的浏览器渲染原理

追忆似水年华 · 1373浏览 · 2019-05-09 22:47:56
基于iview的router常用控制方式

追忆似水年华 · 1000浏览 · 2019-06-03 10:39:21
编程小知识之 JavaScript 文件读取

manongba · 717浏览 · 2019-06-10 09:16:16
10个省时间的 PyCharm 技巧 赶快收藏!

· 703浏览 · 2019-06-10 09:32:01
加载中

0评论

评论
分类专栏
小鸟云服务器
扫码进入手机网页