问题场景:
设计一个路由网关的解决方案, 解决根据不同嵌套路由在访问同一个域名的情况下, 跳转不同的应用程序。
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const url = 'http://url.com';
- 指向a平台的url地址: `${url}/a/login` // a平台 登录页 `${url}/a/home` // a平台 主页 `${url}/a/user` // a平台 个人页 ...
- 指向b平台的url地址: `${url}/b/login` // b平台 登录页 `${url}/b/home` // b平台 主页 `${url}/b/user` // b平台 个人页 ...
|
解决方法:
方案一: 参考 JavaScript 设计模式, 使用 单例模式+策略模式 实现。
使用单例模式实现网关的唯一性, 保证路由的准确性和统一性。
在首次实例化单例模式的同时, 使用策略模式选择网关对应配置方案。
单例模式优点:
- 只需实例化一次, 减小内存使用压力
- 创建实例化后, 不允许被修改
策略模式优点:
- 同一个方法调用, 可通过策略判断选择
- 避免创建多个 if-else
代码示例:
首先, 我们先创建一个通用的接口类SetSingle, 并暴露一个接口名 login()
1 2 3 4
| export interface SetSingle { login(): void; }
|
然后创建不同的子类, 来实现通用接口类里的方法
1 2 3 4 5 6 7 8 9
| import { SetSingle } from '@/../SetSingle';
class ASingle implements SetSingle { public login(): void { console.log('ASingle login'); } } export default ASingle;
|
1 2 3 4 5 6 7 8 9
| import { SetSingle } from '@/../SetSingle';
class BSingle implements SetSingle { public login(): void { console.log('BSingle login'); } } export default BSingle;
|
我们再创建一个最关键的, 单例模式父类, 实例化方法getInstance(), 如果已经实例化方法一次, 则返回自身。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| import { SetSingle } from '@/../SetSingle';
class Context {
private static instance: Context; private single: SetSingle = null;
constructor() { }
public static getInstance() { if (!Context.instance) { Context.instance = new Context(); } return Context.instance; }
public SetSingle(single: SetSingle) { if (this.single == null) { this.single = single; } }
public login() { this.single.login(); } }
export default Context;
|
实例化与使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const context = Context.getInstance();
const path = pathToRegexp('/a/:path(.*)').exec(to.path + ''); if( path !== null ){
context.SetSingle(new ASingle()); context.login(); console.log(context.login())
} else {
context.SetSingle(new BSingle()); context.login(); console.log(context.login()) }
|