装饰者模式
在不改变原对象的基础上,动态地给该对象添加一些额外的功能,就叫做装饰者模式。
应用场景
比如,公司网站的登陆页面如下:
只需要输入账号和密码即可登陆。
例子:
<input type="text" name="user_name" value="Tom" />
<input type="password" name="user_password" value="000" />
<button>submit</button>
// 取得 Dom 元素
var userName = document.querySelector("[name=user_name]"),
userPassword = document.querySelector("[name=user_password]"),
btn = document.querySelector("button");
// 提交函数
var submitFn = function () {
var data = {
name: userName.value,
password: userPassword.value,
};
// 伪代码:提交数据给后台
(function Ajax(data) {
console.log("submit:" + JSON.stringify(data));
})(data);
};
//调用提交函数
btn.addEventListener("click", function () {
submitFn();
});
后来需求有些变化:用户在提交给后台之前,应该做一些必要的校验,比如验证账号和密码是否为空。直接去修改 submitFn 函数自然是最直接的方法,但也是最差的方法。如果既想不改变原函数的代码,又想给该函数新增校验功能,装饰者模式是很好的选择。
例子:
<input type="text" name="user_name" value="Tom" />
<input type="password" name="user_password" value="000" />
<button>submit</button>
// 取得 Dom 元素
var userName = document.querySelector("[name=user_name]"),
userPassword = document.querySelector("[name=user_password]"),
btn = document.querySelector("button");
// 提交函数:不修改
var submitFn = function () {
var data = {
name: userName.value,
password: userPassword.value,
};
(function Ajax(data) {
console.log("submit:" + JSON.stringify(data));
})(data);
};
// 新增校验函数,也就是装饰者函数
// 将提交函数嵌入到装饰者函数里
// 点击提交时,两个函数都可以依次执行
var checkFn = function (callBack) {
var _check = function () {
var userNameBool = userName.value === ""? false : true;
var userPasswordBool = userPassword.value === ""? false : true;
if (userNameBool && userPasswordBool) {
return true;
}
return false;
};
return function () {
if (!_check()) {
console.log("账号和密码不能为空!");
return;
}
callBack();
};
};
// 将装饰者函数再次赋值给变量 submitFn
// 这样可以免于修改调用函数的函数名
submitFn = checkFn(submitFn);
// 调用提交函数
// 此时的提交函数已经新增了校验功能
// 但提交函数本身和调用的函数名都不曾改变,不会影响即存的代码
btn.addEventListener("click", function () {
submitFn();
});
如有错误,欢迎指正,本人不胜感激。
热门评论
学到了 应对需求修改的新思路