设计模式
通俗讲,设计模式只是大量有经验的开发者在面对相同问题时,无数次使用过的解决方案。
可能很多人认为设计模式并没有多大用途,毕竟用普通的方法就能解决的问题,何必把代码逻辑搞得如此复杂,但从代码的可复用性和可维护性来看,好的设计的确可以节省大量的开发成本。优秀的 JavaScript 框架都运用了大量设计模式。
单例模式
单例模式的核心是确保只有一个实例对象,并提供全局访问。
使用场景
试想一下这样的场景,页面有一个登录窗,这个登录窗是唯一的,那么这个登录窗就非常适合用单例模式来创建。
我们可能会选择将这个登录窗定义在全局环境中:
例子:
<button id="login">登录</button>
<script>
var loginBox = (function() {
var div = document.createElement("div");
div.innerHTML = "登录窗";
div.style.backgroundColor = "bisque";
div.style.display = "none";
document.body.appendChild(div);
return div;
})();
document.getElementById("login").onclick = function() {
loginBox.style.display = "block";
};
</script>
例子中,我们将登录窗缓存在全局环境中并隐藏起来,当用户点击时,才开始展示。这种单例模式称为饿汉式单例,即实例在页面加载完成时就被创建。
登录窗定义在全局存在很多问题,容易造成命名空间污染,所以有必要减少全局变量的使用。最为理想的方式是将实例封装在闭包中,只暴漏外部访问的接口。
另外,我们打开页面,可能根本不会点击登录按钮,那么加载的数据只是白白浪费内存而已,因此,与饿汉式单例相反的、实际工作中使用更多的是懒汉式单例,即实例在第一次引用时才被创建,然后将结果缓存在闭包中。
例子:
<button id="login">登录</button>
<script>
var createLoginBox = (function() {
var div;
return function() {
if (!div) {
div = document.createElement("div");
div.innerHTML = "登录窗";
div.style.backgroundColor = "bisque";
document.body.appendChild(div);
}
return div;
}
})();
document.getElementById("login").onclick = function() {
createLoginBox();
};
</script>
通用懒汉式单例
页面中,往往不止一种弹出窗,如果下次我们需要创建确认框,就去复制现有的单例方法,这明显不是明智的做法。
理想的做法是将单例方法中变化的部分抽离出来,然后再以回调函数的形式传回给单例。本例中,创建弹窗的代码是变化的,而管理单例的代码是不变的,因此我们将创建弹窗的代码单独放置在一个方法里,这样一来,原来的单例方法中,只剩下可以通用的代码。
例子:
<button id="login">登录</button>
<button id="confirm">确认</button>
<script>
//管理单例的逻辑始终是一样的
var createSing = function() {
var result;
return function(fn) {
if (!result) {
result = fn();
}
return result;
}
};
//创建登录窗的方法
var createLoginBox = function() {
var div = document.createElement("div");
div.innerHTML = "登录窗";
div.style.backgroundColor = "#ffe4c4";
document.body.appendChild(div);
return div;
};
//创建确认窗的方法
var createConfirmBox = function() {
var div = document.createElement("div");
div.innerHTML = "确认窗";
div.style.backgroundColor = "#ff5722";
document.body.appendChild(div);
return div;
};
//为登录窗创建一个实例
var login = createSing();
document.getElementById("login").onclick = function() {
login(createLoginBox);
};
//为确认窗创建一个实例
var confirm = createSing();
document.getElementById("confirm").onclick = function() {
confirm(createConfirmBox);
};
</script>
如有错误,欢迎指正,本人不胜感激。