装饰器模式
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。其并不深入依赖于对象是如何创建的,而是专注于扩展它的功能上。
优点
- 装饰类和被装饰类独立,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
缺点
- 多层装饰比较复杂。
在实现具体代码前我们需要你对 ES6 装饰器 有个基础的了解
下面我我们实现一个基于 axios 和 装饰器的接口构造方法
先看下最终的如何去使用
import { GET, POST } from "./axiosHelp.js";
// 首页接口 HomeAjax.js
class HomeAjax {
@GET("/api/user")
getUserInfo() {}
@POST("/api/userName")
setUserName(params) {}
}
export default new HomeAjax();
// home.js
import HomeAjax from "./HomeAjax";
HomeAjax.getUserInfo();
HomeAjax.setUserName({ userName: "装饰器模式" }).then((res) => {
console.log("修改用户名成功");
});
复制代码
可以看到上面定义接口时使用了 GET
POST
等修饰函数去修饰对应的接口函数,直观上感觉会比较清晰和统一,那么具体如何去实现呢?
// axiosHelp.js
import axios from "axios";
// 1. 构建一个 axios 实例
const axiosInstance = axios.create({ baseURL: "/" });
// 2. 实现基本的 Request 方法去封装 GET/POST
const Request = (method) => (url) => (
target,
name,
descriptor,
) => {
descriptor.value = function (params) {
const axiosConfig = {
method,
url: url,
};
// 构造 axios 需要的参数
if (params) {
if (method === "get") {
axiosConfig.params = params;
} else {
axiosConfig.data = params;
}
}
const req = axiosInstance({ ...axiosConfig });
return req;
};
return descriptor;
};
// 3. 用封装好的 Request 方法分别构造 GET/POST 装饰函数
export const GET = Request("get");
export const POST = Request("post");
复制代码
以上就是基于 ES6 实现的装饰器模式,实际生产中的 Request 会很复杂其涉及到不同的请求体如 form 类型 json 类型,url 类型,路径参数, encode,异常处理,全局 loading 等。这里做了简化是为了方便大家直观的感受装饰器模式的实现。
我对装饰器模式的理解就是装饰函数使用起来简单且清晰,一看就是到这个方法被装饰后的作用。但是缺点也很明显就是装饰函数的实现比较晦涩,而且多重装饰会比较复杂。
注意:目前浏览器尚未支持该特性,需要 babel 转 stage2 的标准, typescript 需要开放 experimentalDecorators 配置。当然也可以使用传统 function 模式的装饰器,即类似高阶函数的方式。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END