微前端架构中的设计模式应用
微前端架构中的设计模式应用
微前端架构将单体前端应用拆分为多个独立、松耦合的子应用,每个子应用可以独立开发、部署和运行。在这种分布式架构中,设计模式的应用尤为重要,它们能帮助解决跨应用通信、状态管理、样式隔离等常见问题。
单例模式在全局状态管理中的应用
微前端架构中,多个子应用可能需要共享全局状态。单例模式确保全局状态唯一且易于访问:
class GlobalState {
constructor() {
if (GlobalState.instance) {
return GlobalState.instance;
}
this.state = {};
GlobalState.instance = this;
}
set(key, value) {
this.state[key] = value;
}
get(key) {
return this.state[key];
}
}
// 子应用A
const stateA = new GlobalState();
stateA.set('user', { name: 'Alice' });
// 子应用B
const stateB = new GlobalState();
console.log(stateB.get('user')); // { name: 'Alice' }
这种实现方式确保所有子应用访问的是同一个状态实例,避免了状态不一致问题。
发布-订阅模式实现跨应用通信
微前端中,子应用间的通信是关键挑战。发布-订阅模式提供松耦合的解决方案:
class EventBus {
constructor() {
this.events = {};
}
subscribe(event, callback) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(callback);
}
publish(event, data) {
if (this.events[event]) {
this.events[event].forEach(callback => callback(data));
}
}
}
// 主应用初始化事件总线
window.eventBus = new EventBus();
// 子应用A发布事件
window.eventBus.publish('cart-updated', { items: 5 });
// 子应用B订阅事件
window.eventBus.subscribe('cart-updated', data => {
console.log('购物车更新:', data);
});
这种模式允许子应用在不直接依赖彼此的情况下进行通信。
策略模式处理多环境配置
不同子应用可能需要不同的环境配置策略:
class ConfigStrategy {
constructor(strategy) {
this.strategy = strategy;
}
setStrategy(strategy) {
this.strategy = strategy;
}
getConfig() {
return this.strategy.getConfig();
}
}
class DevConfig {
getConfig() {
return {
apiBase: 'https://dev.api.example.com',
debug: true
};
}
}
class ProdConfig {
getConfig() {
return {
apiBase: 'https://api.example.com',
debug: false
};
}
}
// 使用示例
const config = new ConfigStrategy(new DevConfig());
console.log(config.getConfig());
// 运行时切换策略
config.setStrategy(new ProdConfig());
外观模式简化微前端API
为子应用提供统一简化的接口:
class MicroFrontendFacade {
constructor() {
this.router = new RouterService();
this.state = new GlobalState();
this.events = new EventBus();
}
navigateTo(app, path) {
this.router.navigate(app, path);
}
getSharedState(key) {
return this.state.get(key);
}
subscribeToEvent(event, callback) {
this.events.subscribe(event, callback);
}
}
// 子应用中使用
const mfe = new MicroFrontendFacade();
mfe.navigateTo('checkout', '/cart');
mfe.subscribeToEvent('user-logged-in', user => {
console.log('用户登录:', user);
});
代理模式实现懒加载
优化子应用加载性能:
class MicroAppProxy {
constructor(name, loader) {
this.name = name;
this.loader = loader;
this.app = null;
}
async mount(container) {
if (!this.app) {
this.app = await this.loader();
}
return this.app.mount(container);
}
unmount() {
if (this.app) {
return this.app.unmount();
}
}
}
// 使用示例
const checkoutApp = new MicroAppProxy('checkout', () =>
import('https://example.com/checkout-app.js')
);
document.getElementById('checkout-btn').addEventListener('click', () => {
checkoutApp.mount(document.getElementById('app-container'));
});
装饰器模式增强子应用功能
在不修改原有代码的情况下扩展功能:
function withAnalytics(App) {
return class extends App {
mount(container) {
console.log(`[Analytics] 开始加载应用: ${this.name}`);
const startTime = performance.now();
const result = super.mount(container);
const loadTime = performance.now() - startTime;
console.log(`[Analytics] 应用加载完成, 耗时: ${loadTime}ms`);
return result;
}
};
}
// 原始应用类
class CheckoutApp {
constructor() {
this.name = 'Checkout';
}
mount(container) {
console.log('挂载结账应用');
// 实际挂载逻辑
}
}
// 增强后的应用
const EnhancedCheckoutApp = withAnalytics(CheckoutApp);
new EnhancedCheckoutApp().mount(document.body);
组合模式构建应用树
管理复杂的子应用嵌套关系:
class MicroAppComponent {
constructor(name) {
this.name = name;
this.children = [];
}
add(child) {
this.children.push(child);
}
remove(child) {
const index = this.children.indexOf(child);
if (index !== -1) {
this.children.splice(index, 1);
}
}
async mount(container) {
console.log(`挂载 ${this.name}`);
const appContainer = document.createElement('div');
appContainer.id = `app-${this.name}`;
container.appendChild(appContainer);
for (const child of this.children) {
await child.mount(appContainer);
}
}
}
// 使用示例
const dashboard = new MicroAppComponent('dashboard');
const header = new MicroAppComponent('header');
const sidebar = new MicroAppComponent('sidebar');
const mainContent = new MicroAppComponent('main');
dashboard.add(header);
dashboard.add(sidebar);
dashboard.add(mainContent);
// 在main区域添加更多子应用
const productList = new MicroAppComponent('product-list');
const recommendations = new MicroAppComponent('recommendations');
mainContent.add(productList);
mainContent.add(recommendations);
dashboard.mount(document.body);
观察者模式实现样式隔离
class StyleObserver {
constructor() {
this.observers = [];
this.currentApp = null;
}
register(app) {
this.observers.push(app);
}
setActiveApp(appName) {
this.currentApp = appName;
this.notifyAll();
}
notifyAll() {
this.observers.forEach(app => {
app.updateStyles(this.currentApp === app.name);
});
}
}
class MicroApp {
constructor(name, styleObserver) {
this.name = name;
this.styleObserver = styleObserver;
this.styleObserver.register(this);
}
updateStyles(isActive) {
if (isActive) {
document.body.classList.add(`app-${this.name}-active`);
} else {
document.body.classList.remove(`app-${this.name}-active`);
}
}
}
// 使用示例
const styleObserver = new StyleObserver();
const app1 = new MicroApp('checkout', styleObserver);
const app2 = new MicroApp('dashboard', styleObserver);
// 切换应用时
styleObserver.setActiveApp('checkout');
工厂模式创建子应用实例
class MicroAppFactory {
static createApp(type) {
switch (type) {
case 'react':
return new ReactMicroApp();
case 'vue':
return new VueMicroApp();
case 'angular':
return new AngularMicroApp();
default:
throw new Error('未知的应用类型');
}
}
}
class ReactMicroApp {
mount(container) {
console.log('挂载React应用');
// React应用挂载逻辑
}
}
class VueMicroApp {
mount(container) {
console.log('挂载Vue应用');
// Vue应用挂载逻辑
}
}
// 使用示例
const app1 = MicroAppFactory.createApp('react');
const app2 = MicroAppFactory.createApp('vue');
app1.mount(document.getElementById('app1'));
app2.mount(document.getElementById('app2'));
适配器模式整合不同框架子应用
class FrameworkAdapter {
constructor(app) {
this.app = app;
}
mount(container) {
// 统一mount接口
if (this.app.mount) {
return this.app.mount(container);
} else if (this.app.init) {
return this.app.init(container);
} else if (this.app.bootstrap) {
return this.app.bootstrap().then(() => {
this.app.mountComponent(container);
});
}
throw new Error('无法适配的应用接口');
}
unmount() {
// 统一unmount接口
if (this.app.unmount) {
return this.app.unmount();
} else if (this.app.destroy) {
return this.app.destroy();
}
return Promise.resolve();
}
}
// 使用不同框架的子应用
const reactApp = new ReactMicroApp();
const vueApp = new VueMicroApp();
// 统一接口
const adaptedReactApp = new FrameworkAdapter(reactApp);
const adaptedVueApp = new FrameworkAdapter(vueApp);
// 现在可以使用相同的方式操作不同框架的应用
adaptedReactApp.mount(document.getElementById('react-app'));
adaptedVueApp.mount(document.getElementById('vue-app'));
状态模式管理子应用生命周期
class MicroAppState {
constructor(app) {
this.app = app;
}
mount() {
throw new Error('必须实现mount方法');
}
unmount() {
throw new Error('必须实现unmount方法');
}
}
class NotLoadedState extends MicroAppState {
mount() {
console.log(`加载应用: ${this.app.name}`);
return this.app.load().then(() => {
this.app.setState(new LoadedState(this.app));
return this.app.mount();
});
}
unmount() {
console.log('应用未加载,无需卸载');
return Promise.resolve();
}
}
class LoadedState extends MicroAppState {
mount() {
console.log(`挂载已加载的应用: ${this.app.name}`);
// 实际挂载逻辑
return Promise.resolve();
}
unmount() {
console.log(`卸载应用: ${this.app.name}`);
// 实际卸载逻辑
return Promise.resolve();
}
}
class MicroApp {
constructor(name) {
this.name = name;
this.state = new NotLoadedState(this);
}
setState(state) {
this.state = state;
}
mount() {
return this.state.mount();
}
unmount() {
return this.state.unmount();
}
load() {
console.log(`模拟加载应用: ${this.name}`);
return new Promise(resolve => setTimeout(resolve, 1000));
}
}
// 使用示例
const app = new MicroApp('checkout');
app.mount(); // 首次加载并挂载
app.unmount(); // 卸载
app.mount(); // 再次挂载(此时已加载)
备忘录模式实现应用状态快照
class AppMemento {
constructor(state) {
this.state = JSON.parse(JSON.stringify(state));
}
getState() {
return this.state;
}
}
class MicroApp {
constructor() {
this.state = {
user: null,
preferences: {},
lastRoute: '/'
};
}
save() {
return new AppMemento(this.state);
}
restore(memento) {
this.state = memento.getState();
}
updateState(newState) {
this.state = { ...this.state, ...newState };
}
}
// 使用示例
const app = new MicroApp();
app.updateState({ user: { name: 'Alice' } });
// 创建快照
const snapshot1 = app.save();
app.updateState({ lastRoute: '/checkout' });
// 恢复状态
app.restore(snapshot1);
console.log(app.state); // { user: { name: 'Alice' }, preferences: {}, lastRoute: '/' }
职责链模式处理子应用错误
class ErrorHandler {
constructor(successor = null) {
this.successor = successor;
}
handle(error, app) {
if (this.canHandle(error)) {
return this.process(error, app);
} else if (this.successor) {
return this.successor.handle(error, app);
}
throw error;
}
canHandle() {
throw new Error('必须实现canHandle方法');
}
process() {
throw new Error('必须实现process方法');
}
}
class NetworkErrorHandler extends ErrorHandler {
canHandle(error) {
return error.message.includes('Network');
}
process(error, app) {
console.log('处理网络错误:', error.message);
return app.retry();
}
}
class AuthErrorHandler extends ErrorHandler {
canHandle(error) {
return error.message.includes('Auth');
}
process(error) {
console.log('处理认证错误:', error.message);
window.location.href = '/login';
return Promise.resolve();
}
}
class DefaultErrorHandler extends ErrorHandler {
canHandle() {
return true;
}
process(error) {
console.error('未处理的错误:', error);
return Promise.reject(error);
}
}
// 构建责任链
const errorHandler = new NetworkErrorHandler(
new AuthErrorHandler(
new DefaultErrorHandler()
)
);
// 使用示例
class MicroApp {
constructor() {
this.retryCount = 0;
}
async mount() {
try {
// 模拟可能出错的挂载操作
if (Math.random() > 0.5) {
throw new Error('Network error: Failed to fetch');
}
console.log('应用挂载成功');
} catch (error) {
return errorHandler.handle(error, this);
}
}
retry() {
this.retryCount++;
console.log(`重试第 ${this.retryCount} 次`);
return this.mount();
}
}
const app = new MicroApp();
app.mount();
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:前端路由库中的设计模式实现