我已经受够无处不在的分支语句了!
长痛不如短痛,趁现在的底层交互代码还没有这么多,赶紧重构吧。毕竟不是 demo 时期了,要讲究一些了
设计思路
刚开始的想法是整一个抽象类 AbstractAPIs 声明所有待实现的函数,然后让各个平台去具体的实现 PlatformAAPIs、PlatformBAPIs
突然想到 Js 好像没有抽象类,不好意思 TypeScript 写的有点多。。。
如果手动模拟抽象类,如果没被子类覆盖抛异常。这种方式代码量有点太多了,一百多个接口,每个都一样的代码,实在是不优雅
其实抽象类的作用就是起到一个注册的作用,注册存在这么一些方法可供使用。对于这样的注册,没必要真的将其结构化为类,只需要抛出一个对象即可
export default {methodName1: "methodName1",methodName2: "methodName2",methodName3: "methodName3",
}
使用时根据字符串来调用
apis.call(FUNCNAMES.methodName1)
结构框架
platform1.js
class Platform1 {methodName1() { // 实现 }methodName2() { // 实现 }methodName3() { // 实现 }
}
export default new Platform1();
platform2.js
class Platform1 {methodName1() { // 实现 }methodName2() { // 实现 }methodName3() { // 实现 }
}
export default new Platform2();
api.js
import platformA from "./platformA";
import platformB from "./platformB";class Apis {this.instance = window.isPlarformA() ? platformA : platformB;call = (funcName) => {return this.instance[funcName]();}
}export default new Apis();
添加参数支持
当然,调用时不仅有函数名,还有参数,这个要怎么处理呢
apis.call 完全可以仿照 js 的 call,就是 call、apply 那一套的 call,将 params 直接附在后边
apis.call(FUNCNAMES.methodName1, param1, param2, param3...)
在实现 call 的时候解构赋值即可
call = (funcName, ...args) => {return this.instance[funcName](...args);
};
最终实现
class APIs {constructor() {this.bInit = false;this.instance = null;}init = () => {this.bInit = true;this.instance = window.isPlarformA() ? platformA : platformB;};call = (funcName, ...args) => {if (!this.bInit) this.init();if (this.instance[funcName]) {return this.instance[funcName](...args);} else {throw new Error(`[APIs::call][${funcName}] no instance[funcName].`);}};
}