面试题答案
一键面试使用观察者模式管理组件状态
-
观察者模式概述: 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当这个主题对象的状态发生变化时,会通知所有观察者对象,使它们能够自动更新。
-
实现步骤:
- 主题(Subject):维护一个观察者列表,提供添加、移除观察者的方法,以及通知观察者的方法。
- 观察者(Observer):定义一个更新接口,当主题状态变化时,主题会调用此接口通知观察者。
-
代码示例:
// 主题类
class Subject {
constructor() {
this.observers = [];
}
// 添加观察者
attach(observer) {
this.observers.push(observer);
}
// 移除观察者
detach(observer) {
this.observers = this.observers.filter(obs => obs!== observer);
}
// 通知所有观察者
notify() {
this.observers.forEach(observer => observer.update());
}
}
// 观察者类
class Observer {
constructor(name) {
this.name = name;
}
update() {
console.log(`${this.name} 收到状态更新`);
}
}
// 使用示例
const subject = new Subject();
const observer1 = new Observer('观察者1');
const observer2 = new Observer('观察者2');
subject.attach(observer1);
subject.attach(observer2);
// 模拟主题状态变化
subject.notify();
// 移除观察者2
subject.detach(observer2);
// 再次模拟主题状态变化
subject.notify();
避免内存泄漏
- 移除不再需要的观察者:在组件销毁时,确保从主题的观察者列表中移除相关观察者,如上述代码中的
detach
方法。 - 弱引用:在某些情况下,可以使用
WeakMap
来存储观察者,这样当观察者对象没有其他引用时,垃圾回收机制可以回收它,避免内存泄漏。例如:
class Subject {
constructor() {
this.observers = new WeakMap();
}
attach(observer, context) {
this.observers.set(observer, context);
}
detach(observer) {
this.observers.delete(observer);
}
notify() {
this.observers.forEach((context, observer) => observer.update(context));
}
}
其他合适的设计模式
- 状态模式:当组件的状态复杂且有多种状态转换时,状态模式可以将每个状态封装成独立的类,使状态转换逻辑更加清晰。例如,一个按钮组件可能有 “正常”、“按下”、“禁用” 等状态,每个状态可以是一个独立的类,负责处理该状态下的行为。
- 单例模式:如果组件需要全局唯一的状态管理对象,可以使用单例模式。例如,一个应用的用户登录状态管理,只需要一个实例来管理登录状态,避免重复创建造成的资源浪费和状态不一致。
// 单例模式示例
class LoginManager {
constructor() {
if (LoginManager.instance) {
return LoginManager.instance;
}
this.isLoggedIn = false;
LoginManager.instance = this;
}
login() {
this.isLoggedIn = true;
console.log('用户登录');
}
logout() {
this.isLoggedIn = false;
console.log('用户登出');
}
}
// 使用示例
const manager1 = new LoginManager();
const manager2 = new LoginManager();
console.log(manager1 === manager2); // true
在实际的复杂UI组件开发中,根据具体需求可能会综合运用多种设计模式来更好地管理组件状态和行为。