单例模式在路由配置中的应用
项目里经常需要一个统一的路由表,既不能重复创建,又要全局可访问。这时候单例模式就派上用场了。比如我们定义一个路由管理器,确保整个应用中只存在一份路由配置。
class RouterManager {
constructor() {
if (RouterManager.instance) {
return RouterManager.instance;
}
this.routes = new Map();
RouterManager.instance = this;
return this;
}
addRoute(path, handler) {
this.routes.set(path, handler);
}
getRoute(path) {
return this.routes.get(path);
}
}
// 使用方式
const router = new RouterManager();
const anotherRouter = new RouterManager();
console.log(router === anotherRouter); // true这样不管在哪引入,拿到的都是同一个实例,避免了数据不一致的问题。
观察者模式实现路由变化监听
当用户点击跳转或浏览器前进后退时,我们希望某些模块能自动响应。比如页面标题更新、导航高亮切换。观察者模式让这些依赖关系变得清晰又解耦。
class RouteObserver {
constructor() {
this.listeners = [];
}
on(callback) {
this.listeners.push(callback);
}
emit(path) {
this.listeners.forEach(fn => fn(path));
}
}
// 模拟路由变更
window.addEventListener('popstate', () => {
const currentPath = window.location.pathname;
routeObserver.emit(currentPath);
});
const routeObserver = new RouteObserver();
routeObserver.on((path) => {
console.log('当前路径:', path);
});组件只需要订阅自己关心的事件,不用主动去轮询状态。
工厂模式动态生成路由处理器
不同类型的页面可能需要不同的处理逻辑,比如静态页、权限页、异步加载页。我们可以用工厂模式根据配置返回对应的处理器。
function routeHandlerFactory(config) {
switch (config.type) {
case 'async':
return async () => {
const module = await import(config.modulePath);
return module.default();
};
case 'auth':
return () => {
if (checkAuth()) {
renderPage(config.component);
} else {
redirectTo('/login');
}
};
default:
return () => renderPage(config.component);
}
}路由配置变得更灵活,扩展新类型也不用改核心逻辑。
装饰器模式增强路由行为
想给某些路由加埋点、日志或权限校验?装饰器模式可以在不修改原函数的前提下附加功能。
function withLog(target, name, descriptor) {
const original = descriptor.value;
descriptor.value = function(...args) {
console.log(`进入路由: ${name}, 参数:`, args);
return original.apply(this, args);
};
return descriptor;
};
class PageController {
@withLog
home() {
renderHome();
}
}代码职责分明,横切关注点集中管理。