面试题答案
一键面试解耦方式
- 抽象耦合:
- 在观察者模式中,主体(Subject)和观察者(Observer)通过抽象接口进行交互。主体只知道观察者实现了某个特定的观察者接口,而不关心具体的观察者类。这样主体与具体观察者之间不存在紧密的类依赖关系。
- 观察者也只依赖于主体提供的抽象主题接口,而不是主体的具体实现类。
- 注册与通知机制:
- 主体通过维护一个观察者列表,采用注册(register)和注销(deregister)的方式管理观察者。主体并不需要知道每个观察者具体的行为逻辑,只是在状态变化时向所有注册的观察者发送通知。
- 观察者在注册时将自身传递给主体,这样主体就可以在合适的时机调用观察者的更新方法,而不需要在主体内部硬编码具体的观察者操作。
代码示例
// 抽象观察者接口
interface Observer {
void update(String message);
}
// 具体观察者类
class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " 收到消息: " + message);
}
}
// 抽象主题接口
interface Subject {
void registerObserver(Observer observer);
void deregisterObserver(Observer observer);
void notifyObservers(String message);
}
// 具体主题类
class ConcreteSubject implements Subject {
private java.util.List<Observer> observers = new java.util.ArrayList<>();
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void deregisterObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
// 测试类
public class ObserverPatternDemo {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
ConcreteObserver observer1 = new ConcreteObserver("观察者1");
ConcreteObserver observer2 = new ConcreteObserver("观察者2");
subject.registerObserver(observer1);
subject.registerObserver(observer2);
subject.notifyObservers("新消息发布啦!");
subject.deregisterObserver(observer2);
subject.notifyObservers("又有新消息啦!");
}
}
在上述代码中,Subject
接口和 Observer
接口定义了主体和观察者之间交互的抽象方法。ConcreteSubject
类通过维护 Observer
列表实现注册、注销和通知观察者的功能,它并不关心 Observer
具体的实现。ConcreteObserver
类实现 Observer
接口,具体处理接收到的通知,它也只依赖于 Subject
的抽象接口,而不是具体的 ConcreteSubject
类。通过这种方式,主体与观察者之间实现了解耦。