JavaScript设计模式:策略模式详解与实战

作者:闭包旅人时间:2026-10-29 20:22:08浏览:268

本文深入解析JavaScript中的策略模式,旨在将不变部分与变化部分分离。通过奖金计算和表单验证两个具体案例,展示如何封装一系列可相互替换的算法。文章提供了完整的代码实现,帮助开发者理解Context与策略类的协作机制,提升代码的灵活性与可维护性。

策略模式的核心思想

每个设计模式的核心主题,在于将程序中相对稳定的部分与频繁变化的部分进行有效隔离。

  • 解决同一问题往往存在多种路径。以文件压缩为例,既可以选择zip算法,也可以采用gzip算法。面对这种灵活多样的需求,策略模式提供了一种优雅的解决方案。

策略模式的定义与结构

一、定义

策略模式定义了一系列算法,将它们分别封装起来,并使这些算法之间可以互相替换。 基于策略模式的程序结构至少包含两个部分:一是策略类集合,负责封装具体算法并执行计算逻辑;二是环境类Context,负责接收客户端请求,并将请求委托给对应的策略类执行。

策略模式实战:奖金计算

二、示例

计算员工奖金。根据绩效等级发放不同倍数的工资:绩效为S级时发放4倍工资,A级发放3倍工资,B级发放2倍工资。


var strategies = {
 "S": function(salary) {
  return salary * 4;
 },
 "A": function(salary) {
  return salary * 3;
 },
 "B": function(salary) {
  return salary * 2;
 }
};

// 接收请求
var calculateBonus = function(level, salary) {
 return strategies[level](salary);
};

// 测试
console.log(calculateBonus("S", 20000));
console.log(calculateBonus("A", 20000));
console.log(calculateBonus("B", 20000));

策略模式应用:表单验证

三、延伸:表单验证


/* 校验策略对象 */
var validateStrategies = {
 isEmpty: function (val, errorMsg) {
  if (!val) {
   return errorMsg;
  }
 },
 isURL: function (val, errorMsg) {
  if (!new RegExp("^(http:\\/\\/|https:\\/\\/)?([\\w\\-]+\\.)+[\\w\\-]+(\\/[\\w\\-\\.\\/?\\@\\%\\!\\&=\\+\\~\\:\\#\\;\\,]*)?$").test(val)) {
   return errorMsg;
  }
 },
 isEmail: function (val, errorMsg) {
  if (!new RegExp('\\w+((-\\w+)|(\\.\\w+))*\\@[A-Za-z0-9]+((\\.|-)[A-Za-z0-9]+)*\\.[A-Za-z0-9]+').test(val)) {
   return errorMsg;
  }
 },
 isMaxLength: function (val, length, errorMsg) {
  if (val.length > length) {
   return errorMsg;
  }
 },
 isMinLength: function (val, length, errorMsg) {
  if (val.length < length) {
   return errorMsg;
  }
 }
};

/* validator类 */
var validator = function () {
 // 缓存验证策略
 this.cache = [];
};

/**
 * 添加要验证的策略
 * @param dom  要验证的dom元素
 * @param rules  验证规则
 */
validator.prototype.add = function (dom, rules) {
 var self = this;
 for (var i = 0, rule; rule = rules[i++];) {
  (function (rule) {
   var strategyAry = rule.strategy.split(":");  // ["isMaxLength", "10"]
   var errorMsg = rule.errorMsg;     // "内容长度不能超过10"
   self.cache.push(function () {
    var strategy = strategyAry.shift();   // "isMaxLength"
    strategyAry.unshift(dom.value);    // ["1@qq", "10"]
    strategyAry.push(errorMsg);     // ["1@qq", "10", "内容长度不能超过10"]
    return validateStrategies[strategy].apply(dom, strategyAry);
   });
  })(rule);
 }
};

/* 开始校验 */
validator.prototype.start = function () {
 for (var i = 0, validateFunc; validateFunc = this.cache[i++];) {
  var errorMsg = validateFunc();
  if (errorMsg) {
   return errorMsg;
  }
 }
};


// 测试

<label for="email">邮箱:</label><input type="text" name="email" value="1@qq">

var validatorInstance = new validator();
validatorInstance.add(
 document.getElementsByName("email")[0], 
 [{
  strategy: "isEmpty",
  errorMsg: "内容不能为空"
 },{
  strategy: "isMaxLength:10",
  errorMsg: "内容长度不能超过10"
 },{
  strategy: "isEmail",
  errorMsg: "email格式不对"
 }]);
errorMsg = validatorInstance.start();

希望本文所述内容能对大家学习JavaScript程序设计有所帮助。

作者最新文章