装饰器就是动态给对象添加职责。
aop实现方式。
/*在方法调用之前添加职责(功能) */
Function.prototype.before = function (beforefn) {
var __self = this; // 保存原函数的引用
return function () { // 返回包含了原函数和新函数的"代理"函数
beforefn.apply(this, arguments); // 执行新函数,且保证this不被劫持,新函数接受的参数
// 也会被原封不动地传入原函数,新函数在原函数之前执行
return __self.apply(this, arguments); // 执行原函数并返回原函数的执行结果, // 并且保证this不被劫持
}
}
/**在方法调用之后添加功能 */
Function.prototype.after = function (afterfn) {
var __self = this; return function () {
var ret = __self.apply(this, arguments);
afterfn.apply(this, arguments); return ret;
}
};
var ajax = function (type, url, param) {
console.log(param); // 发送 ajax 请求的代码略
};
var getToken = function () { return 'Token'; }
ajax = ajax.before(function (type, url, param) {
param.Token = getToken();
});
ajax('get', 'http:// xxx.com/userinfo', { name: 'sven' });
使用装饰器模式可以改变函数的参数,如上面,我们使用before
将ajax
的参数增加了一个token
参数。
表单提交中,将表单校验和表单提交分离开来,避免原本的表单提交函数过于臃肿,符合单一职责原则。
Function.prototype.before = function(beforefn) {
var __self = this;
return function() {
if (beforefn.apply(this, arguments) === false) {
// beforefn返回false的情况直接return,不再执行后面的原函数
return;
}
return __self.apply(this, arguments);
}
}
/**模拟表单空间的数据 */
var username = ''
, password = '123'
var validata = function() {
if (username === '') {
alert('用户名不能为空');
return false;
}
if (password === '') {
alert('密码不能为空');
return false;
}
}
var ajax = function(type, url, param) {
console.log(param);
// 发送 ajax 请求的代码略
};
var formSubmit = function() {
var param = {
username: username.value,
password: password.value
}
ajax('http:// xxx.com/login', param);
}
formSubmit = formSubmit.before(validata);
formSubmit();
在进入mock接口时,打印出请求参数query(url)和body(主体)
/**
* @auther fengli
* 使用了装饰器模式,给方法添加打印功能
*/
/**
* 在方法调用之前添加职责(功能)
*
* @author fengli
* @date 2020-05-07
* @export
* @param {*} fn
* @param {*} beforefn
* @returns
*/
export function before(fn, beforefn) {
return function (req, res) { // 返回包含了原函数和新函数的"代理"函数
beforefn.apply(this, arguments); // 执行新函数,且保证this不被劫持,新函数接受的参数
// 也会被原封不动地传入原函数,新函数在原函数之前执行
return fn.apply(this, arguments); // 执行原函数并返回原函数的执行结果, // 并且保证this不被劫持
}
}
/**
* 在方法调用之后添加功能
*
* @author fengli
* @date 2020-05-07
* @export
* @param {*} fn
* @param {*} afterfn
* @returns
*/
export function after(fn, afterfn) {
return function () {
var ret = fn.apply(this, arguments);
afterfn.apply(this, arguments);
return ret;
}
}
/**
* 打印处request的url及请求参数
*
* @author fengli
* @date 2020-05-07
* @export
* @param {*} req
*/
export function logReq(req) {
console.log('url:', req.originalUrl);
console.log('query:', req.query);
console.log('body', req.body);
}
export function logRes(req, res) {
//console.log('res', res.getHeaderNames())
}
mock接口
import { before, logReq } from './log'
export default {
'GET /api/protectionZoneFillSubmit/getListByPage': before(getListByPage, logReq),
};
function getListByPage(req, res) {
const template = {
'id|+1': 1,
'submitTime|1': [2015, 2016, 2017, 2018, 2019, 2020],
'name|1': ['府河支流徐家河水域银鱼国家级水产种质资源保护区', '堵河鳜国家级水产种质资源保护区', '汉江郧县段翘嘴鲌国家级水产种质资源保护区'],
'latitude|1': ['北纬31.200000°——31°', '北纬32°——32.111°', '北纬32.01°——32.59°'],
'longitude|1': ['东经113.12°——113.45°', '东经110.31°——110.31°', '东经110°——111°'],
'currentProtectionArea|1': [3840, 4000, 1250],
'majorProtectObject|1': ['银鱼', '鳜、大眼鳜、斑鳜,其它保护对象包括蒙古鲌、鲶、鲢、鳙等重要经济鱼类及其生态环境', '翘嘴鲌、蒙古红鲌、拟尖头红鲌、鳡鱼、青草鲢鳙'],
'approveTime|1': ['2014-11-25', '2013-11-11'],
'approveDocNumber|1': ['中华人民共和国农业部公告第2181号', '中华人民共和国农业部公告〔2018〕号'],
'managerOrgName|1': ['广水市水产局渔政执法大队', '十堰市郧阳区水产局'],
submitUnit: '湖北省-随州市-广水市',
'status|1': ['省审批', '专家审批', '已通过', '被驳回', '未上报']
};
const { pageSize, pageNo } = req.query;
let nameAndRule = `records|${pageSize}`;
let tempObj = {};
tempObj[nameAndRule] = [template];
const data = Mock.mock(tempObj)
data.total = 100;
data.current = +pageNo;
data.size = +pageSize;
return res.json({ code: 200, data: data })
}
装饰器模式就是动态给对象添加职责
代理模式和装饰者模式最重要的区别在于它们的意图和设计目的。代理模式的目的是,当直 接访问本体不方便或者不符合需要时,为这个本体提供一个替代者。本体定义了关键功能,而代 理提供或拒绝对它的访问,或者在访问本体之前做一些额外的事情。装饰者模式的作用就是为对 象动态加入行为。换句话说,代理模式强调一种关系(Proxy与它的实体之间的关系) ,这种关系 可以静态的表达,也就是说,这种关系在一开始就可以被确定。而装饰者模式用于一开始不能确 定对象的全部功能时。代理模式通常只有一层代理本体的引用,而装饰者模式经常会形成一条 长长的装饰链。
java中的装饰器模式