前言本系列文章主要根据《JavaScript设计模式与开发实践》整理而来,其中会加入了一些自己的思考。希望对大家有所帮助。文章系列js设计模式–单例模式js设计模式–策略模式js设计模式–代理模式js设计模式–迭代器模式js设计模式–发布订阅模式js设计模式–命令模式js设计模式–组合模式概念模板方法模式是一种只需使用继承就可以实现的非常简单的模式。模板方法模式由两部分结构组成,第一部分是抽象父类,第二部分是具体的实现子类。通常 在抽象父类中封装了子类的算法框架,包括实现一些公共方法以及封装子类中所有方法的执行顺序。子类通过继承这个抽象类,也继承了整个算法结构,并且可以选择重写父类的方法。场景一般用于可以抽取公共方法,例如泡咖啡和泡茶,我们可以抽取烧水 清洗杯具 冲泡等过程优缺点优点可以复用公共方法,子类也不需要实现算法部分例子模板引擎我们实现一个简单的模板引擎:<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <meta name=“viewport” content=“width=device-width, initial-scale=1.0”> <meta http-equiv=“X-UA-Compatible” content=“ie=edge”> <title>Document</title></head><body> <div id=“nav”></div> <script> var formateStr = function (param, data) { return param.replace(/{#(\w+)#}/g, function (match, key) { return typeof data[key] === undefined ? "" : data[key]; }); }; var Nav = function (data) { var _this = this; _this.item = ‘<li><a href="{#hrefUrl#}" title="{#title#}" {#sign#}>{#content#}</a></li>’; _this.html = ‘<ul>’; for (var i = 0, l = data.length; i < l; i++) { _this.html += formateStr(_this.item, data[i]); } _this.html += ‘</ul>’; return _this.html; } var objNav = document.getElementById(’nav’); objNav.innerHTML = Nav([{ hrefUrl: ‘http://www.baidu.com’, content: ‘百度一下’ }, { hrefUrl: ‘http://www.zhihu.com’, content: ‘知乎一下’ } ]); </script></body></html>现在产品加了一个需求,想在content后面加个span标签展示访问次数新需求普通程序员就会动手去改Nav方法,但这违背了开放封闭原则,我们也不能确保不影响原来的功能,其实我们加多一个模板方法就可以规避这样的问题<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <meta name=“viewport” content=“width=device-width, initial-scale=1.0”> <meta http-equiv=“X-UA-Compatible” content=“ie=edge”> <title>Document</title></head><body> <div id=“nav”></div> <script> var formateStr = function (param, data) { return param.replace(/{#(\w+)#}/g, function (match, key) { return typeof data[key] === undefined ? "" : data[key]; }); }; var Nav = function (data) { var _this = this; _this.item = ‘<li><a href="{#hrefUrl#}" title="{#title#}" {#sign#}>{#content#}</a></li>’; _this.html = ‘<ul>’; for (var i = 0, l = data.length; i < l; i++) { _this.html += formateStr(_this.item, data[i]); } _this.html += ‘</ul>’; return _this.html; } var infoNav = function (data) { var _this = this; _this.info = ‘<span>{#clickNum#}</span>’; for (var i = data.length - 1; i >= 0; i–) { data[i].content += formateStr(_this.info, data[i]); }; return Nav.call(this, data); }; var objNav = document.getElementById(’nav’); objNav.innerHTML = infoNav([{ hrefUrl: ‘http://www.baidu.com’, content: ‘百度一下’, title: ‘百度’, clickNum: ‘10’, sign: ‘sign=“1”’ }, { hrefUrl: ‘http://www.zhihu.com’, content: ‘知乎一下’, title: ‘知乎’, clickNum: ‘100’, sign: ‘sign=“2”’ } ]); </script></body></html>