tech-interview-for-developer:观察者模式实战-发布订阅事件驱动

tech-interview-for-developer:观察者模式实战-发布订阅事件驱动

【免费下载链接】tech-interview-for-developer 👶🏻 신입 개발자 전공 지식 & 기술 면접 백과사전 📖 【免费下载链接】tech-interview-for-developer 项目地址: https://gitcode.com/GitHub_Trending/te/tech-interview-for-developer

🎯 读完本文你能得到什么?

  • ✅ 观察者模式(Observer Pattern)的核心概念与设计原理
  • ✅ 发布-订阅(Publish-Subscribe)机制的实现细节
  • ✅ Java内置Observable类的实战应用与局限性
  • ✅ 多线程环境下的观察者模式安全实现
  • ✅ 真实业务场景中的观察者模式最佳实践
  • ✅ 事件驱动架构的设计思路与性能优化

🔍 观察者模式:为什么它是现代软件架构的基石?

"你还在为组件间复杂的依赖关系而头疼吗?观察者模式让松耦合成为现实!"

观察者模式(Observer Pattern)是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会自动收到通知并更新。这种模式是事件驱动编程和响应式系统的核心基础。

📊 观察者模式 vs 发布订阅模式

mermaid

特性观察者模式发布订阅模式
耦合度相对紧耦合完全解耦
通信方式直接调用通过消息代理
性能同步,可能阻塞异步,高性能
复杂度简单易实现需要中间件支持

🛠️ 核心组件与接口设计

1. 主题(Subject)接口

/**
 * 主题接口 - 定义被观察对象的契约
 */
public interface Subject {
    // 注册观察者
    void registerObserver(Observer observer);
    
    // 移除观察者
    void removeObserver(Observer observer);
    
    // 通知所有观察者
    void notifyObservers();
    
    // 设置状态变化(可选)
    void setState(Object state);
    
    // 获取当前状态(可选)
    Object getState();
}

2. 观察者(Observer)接口

/**
 * 观察者接口 - 定义观察者的更新行为
 */
public interface Observer {
    // 当主题状态变化时被调用
    void update(Subject subject, Object args);
    
    // 获取观察者标识(用于去重等)
    String getObserverId();
}

3. 具体主题实现

/**
 * 新闻发布系统 - 具体主题实现
 */
public class NewsPublisher implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String latestNews;
    private boolean changed = false;
    
    @Override
    public void registerObserver(Observer observer) {
        if (!observers.contains(observer)) {
            observers.add(observer);
            System.out.println("观察者注册成功: " + observer.getObserverId());
        }
    }
    
    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
        System.out.println("观察者移除成功: " + observer.getObserverId());
    }
    
    @Override
    public void notifyObservers() {
        if (!changed) return;
        
        List<Observer> observersLocal;
        synchronized (this) {
            observersLocal = new ArrayList<>(observers);
            changed = false;
        }
        
        for (Observer observer : observersLocal) {
            observer.update(this, latestNews);
        }
    }
    
    public void publishNews(String news) {
        this.latestNews = news;
        this.changed = true;
        notifyObservers();
    }
    
    // 线程安全的批量通知
    public void publishNewsAsync(String news) {
        this.latestNews = news;
        this.changed = true;
        
        new Thread(() -> {
            notifyObservers();
        }).start();
    }
}

🎭 多种观察者实现策略

1. 邮件订阅观察者

public class EmailSubscriber implements Observer {
    private String email;
    private String subscriberId;
    
    public EmailSubscriber(String email, String subscriberId) {
        this.email = email;
        this.subscriberId = subscriberId;
    }
    
    @Override
    public void update(Subject subject, Object args) {
        String news = (String) args;
        System.out.println("发送邮件到 " + email + ": " + news);
        // 实际发送邮件逻辑
        sendEmail(news);
    }
    
    private void sendEmail(String content) {
        // 模拟邮件发送
        System.out.println("📧 邮件已发送: " + content.substring(0, Math.min(50, content.length())) + "...");
    }
    
    @Override
    public String getObserverId() {
        return "email-" + subscriberId;
    }
}

2. 消息通知观察者

public class MessageSubscriber implements Observer {
    private String contactInfo;
    private String subscriberId;
    
    public MessageSubscriber(String contactInfo, String subscriberId) {
        this.contactInfo = contactInfo;
        this.subscriberId = subscriberId;
    }
    
    @Override
    public void update(Subject subject, Object args) {
        String news = (String) args;
        System.out.println("发送消息到 " + contactInfo + ": " + news);
        sendMessage(news);
    }
    
    private void sendMessage(String content) {
        // 模拟消息发送
        System.out.println("📱 消息已发送: " + content.substring(0, Math.min(30, content.length())) + "...");
    }
    
    @Override
    public String getObserverId() {
        return "message-" + subscriberId;
    }
}

3. 推送通知观察者

public class PushNotificationSubscriber implements Observer {
    private String deviceId;
    private String subscriberId;
    
    public PushNotificationSubscriber(String deviceId, String subscriberId) {
        this.deviceId = deviceId;
        this.subscriberId = subscriberId;
    }
    
    @Override
    public void update(Subject subject, Object args) {
        String news = (String) args;
        System.out.println("发送推送到设备 " + deviceId + ": " + news);
        sendPushNotification(news);
    }
    
    private void sendPushNotification(String content) {
        // 模拟推送通知
        System.out.println("📲 推送通知已发送: " + content.substring(0, Math.min(40, content.length())) + "...");
    }
    
    @Override
    public String getObserverId() {
        return "push-" + subscriberId;
    }
}

⚡ Java内置Observable类的实战应用

Java提供了内置的Observable类和Observer接口,但在实际项目中需要谨慎使用:

import java.util.Observable;
import java.util.Observer;

/**
 * 使用Java内置Observable的新闻发布器
 */
public class JavaBuiltInNewsPublisher extends Observable {
    private String news;
    
    public void setNews(String news) {
        this.news = news;
        setChanged(); // 必须调用此方法
        notifyObservers(news); // 通知所有观察者
    }
    
    public String getNews() {
        return news;
    }
}

/**
 * 内置Observer接口的实现
 */
public class BuiltInNewsSubscriber implements Observer {
    private String subscriberName;
    
    public BuiltInNewsSubscriber(String subscriberName) {
        this.subscriberName = subscriberName;
    }
    
    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof JavaBuiltInNewsPublisher) {
            String news = (String) arg;
            System.out.println(subscriberName + " 收到新闻: " + news);
        }
    }
}

⚠️ Java内置实现的局限性

  1. Observable是类而不是接口 - 限制了继承灵活性
  2. 没有线程安全保证 - 需要自行处理同步
  3. API设计较为陈旧 - 缺乏现代函数式编程支持
  4. setChanged()方法保护级别 - 限制了扩展性

🚀 高级特性与最佳实践

1. 事件对象封装

/**
 * 新闻事件对象 - 封装事件详细信息
 */
public class NewsEvent {
    private final String title;
    private final String content;
    private final Date publishTime;
    private final String category;
    private final int priority; // 优先级:1-高,2-中,3-低
    
    public NewsEvent(String title, String content, String category, int priority) {
        this.title = title;
        this.content = content;
        this.publishTime = new Date();
        this.category = category;
        this.priority = priority;
    }
    
    // Getter方法
    public String getTitle() { return title; }
    public String getContent() { return content; }
    public Date getPublishTime() { return publishTime; }
    public String getCategory() { return category; }
    public int getPriority() { return priority; }
    
    @Override
    public String toString() {
        return String.format("[%s] %s - %s", category, title, 
            content.substring(0, Math.min(50, content.length())));
    }
}

2. 支持泛型的观察者接口

/**
 * 泛型观察者接口 - 支持不同类型的事件
 * @param <T> 事件类型
 */
public interface GenericObserver<T> {
    void onEvent(T event);
    String getObserverId();
    boolean supportsEventType(Class<?> eventType);
}

/**
 * 泛型主题接口
 * @param <T> 事件类型
 */
public interface GenericSubject<T> {
    void registerObserver(GenericObserver<T> observer);
    void removeObserver(GenericObserver<T> observer);
    void notifyObservers(T event);
    void notifyObserversAsync(T event);
}

3. 基于优先级的事件分发

/**
 * 支持优先级的事件分发器
 */
public class PriorityEventDispatcher implements GenericSubject<NewsEvent> {
    private final Map<Integer, List<GenericObserver<NewsEvent>>> priorityObservers = new ConcurrentHashMap<>();
    private final ExecutorService executor = Executors.newFixedThreadPool(4);
    
    @Override
    public void registerObserver(GenericObserver<NewsEvent> observer) {
        // 根据观察者支持的事件类型分配优先级
        int priority = determinePriority(observer);
        priorityObservers.computeIfAbsent(priority, k -> new CopyOnWriteArrayList<>())
                        .add(observer);
    }
    
    private int determinePriority(GenericObserver<NewsEvent> observer) {
        // 根据业务逻辑确定优先级
        if (observer instanceof EmergencyNewsHandler) {
            return 1; // 最高优先级
        } else if (observer instanceof PremiumSubscriber) {
            return 2; // 高优先级
        }
        return 3; // 普通优先级
    }
    
    @Override
    public void notifyObservers(NewsEvent event) {
        // 按优先级顺序通知
        for (int priority = 1; priority <= 3; priority++) {
            List<GenericObserver<NewsEvent>> observers = priorityObservers.get(priority);
            if (observers != null) {
                for (GenericObserver<NewsEvent> observer : observers) {
                    if (observer.supportsEventType(event.getClass())) {
                        observer.onEvent(event);
                    }
                }
            }
        }
    }
    
    @Override
    public void notifyObserversAsync(NewsEvent event) {
        executor.submit(() -> notifyObservers(event));
    }
    
    // 其他方法实现...
}

🔧 多线程环境下的线程安全实现

1. 使用CopyOnWriteArrayList保证线程安全

public class ThreadSafeNewsPublisher implements Subject {
    private final List<Observer> observers = new CopyOnWriteArrayList<>();
    private volatile String latestNews;
    private volatile boolean changed = false;
    private final Object lock = new Object();
    
    @Override
    public void registerObserver(Observer observer) {
        if (!observers.contains(observer)) {
            observers.add(observer);
        }
    }
    
    @Override
    public void notifyObservers() {
        if (!changed) return;
        
        // 创建观察者列表的快照
        List<Observer> observersSnapshot = new ArrayList<>(observers);
        boolean currentChanged;
        
        synchronized (lock) {
            currentChanged = changed;
            changed = false;
        }
        
        if (currentChanged) {
            for (Observer observer : observersSnapshot) {
                try {
                    observer.update(this, latestNews);
                } catch (Exception e) {
                    // 处理单个观察者的异常,不影响其他观察者
                    System.err.println("观察者处理异常: " + e.getMessage());
                }
            }
        }
    }
}

2. 使用ReentrantReadWriteLock优化读写性能

public class OptimizedNewsPublisher implements Subject {
    private final List<Observer> observers = new ArrayList<>();
    private String latestNews;
    private boolean changed = false;
    private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    
    @Override
    public void registerObserver(Observer observer) {
        rwLock.writeLock().lock();
        try {
            if (!observers.contains(observer)) {
                observers.add(observer);
            }
        } finally {
            rwLock.writeLock().unlock();
        }
    }
    
    @Override
    public void notifyObservers() {
        List<Observer> observersSnapshot;
        boolean currentChanged;
        
        rwLock.readLock().lock();
        try {
            if (!changed) return;
            observersSnapshot = new ArrayList<>(observers);
            currentChanged = changed;
            changed = false;
        } finally {
            rwLock.readLock().unlock();
        }
        
        if (currentChanged) {
            for (Observer observer : observersSnapshot) {
                observer.update(this, latestNews);
            }
        }
    }
}

📈 性能优化与监控

1. 观察者执行时间监控

public class MonitoredObserver implements Observer {
    private final Observer delegate;
    private final String observerName;
    private final MetricsCollector metrics;
    
    public MonitoredObserver(Observer delegate, String observerName, MetricsCollector metrics) {
        this.delegate = delegate;
        this.observerName = observerName;
        this.metrics = metrics;
    }
    
    @Override
    public void update(Subject subject, Object args) {
        long startTime = System.nanoTime();
        try {
            delegate.update(subject, args);
            long duration = System.nanoTime() - startTime;
            metrics.recordSuccess(observerName, duration);
        } catch (Exception e) {
            long duration = System.nanoTime() - startTime;
            metrics.recordFailure(observerName, duration, e);
            throw e;
        }
    }
    
    @Override
    public String getObserverId() {
        return delegate.getObserverId();
    }
}

2. 批量事件处理优化

public class BatchEventProcessor {
    private final BlockingQueue<NewsEvent> eventQueue = new LinkedBlockingQueue<>();
    private final ExecutorService processorThread;
    private volatile boolean running = true;
    private final List<GenericObserver<NewsEvent>> observers;
    
    public BatchEventProcessor(List<GenericObserver<NewsEvent>> observers) {
        this.observers = observers;
        this.processorThread = Executors.newSingleThreadExecutor();
        startProcessing();
    }
    
    public void submitEvent(NewsEvent event) {
        eventQueue.offer(event);
    }
    
    private void startProcessing() {
        processorThread.submit(() -> {
            while (running || !eventQueue.isEmpty()) {
                try {
                    List<NewsEvent> batch = new ArrayList<>();
                    // 批量获取事件(最多等待100ms或收集10个事件)
                    NewsEvent event = eventQueue.poll(100, TimeUnit.MILLISECONDS);
                    if (event != null) {
                        batch.add(event);
                        eventQueue.drainTo(batch, 9); // 再收集最多9个
                    }
                    
                    if (!batch.isEmpty()) {
                        processBatch(batch);
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
    }
    
    private void processBatch(List<NewsEvent> batch) {
        for (GenericObserver<NewsEvent> observer : observers) {
            for (NewsEvent event : batch) {
                if (observer.supportsEventType(event.getClass())) {
                    observer.onEvent(event);
                }
            }
        }
    }
    
    public void shutdown() {
        running = false;
        processorThread.shutdown();
    }
}

🎯 真实业务场景应用

1. 电商订单状态通知系统

mermaid

2. 微服务架构中的事件驱动

/**
 * 分布式事件发布器 - 支持跨服务事件通知
 */
public class DistributedEventPublisher implements Subject {
    private final List<Observer> localObservers = new CopyOnWriteArrayList<>();
    private final MessageQueueClient mqClient;
    private final String serviceName;
    
    public DistributedEventPublisher(MessageQueueClient mqClient, String serviceName) {
        this.mqClient = mqClient;
        this.serviceName = serviceName;
    }
    
    @Override
    public void notifyObservers() {
        // 本地观察者通知
        for (Observer observer : localObservers) {
            observer.update(this, null);
        }
        
        // 分布式事件发布
        DistributedEvent event = createDistributedEvent();
        mqClient.publish(event);
    }
    
    private DistributedEvent createDistributedEvent() {
        return new DistributedEvent(
            serviceName,
            "STATE_CHANGE",
            System.currentTimeMillis(),
            Collections.singletonMap("state", getState())
        );
    }
    
    // 处理来自其他服务的远程事件
    public void handleRemoteEvent(DistributedEvent event) {
        if (!event.getSourceService().equals(serviceName)) {
            setState(event.getPayload().get("

【免费下载链接】tech-interview-for-developer 👶🏻 신입 개발자 전공 지식 & 기술 면접 백과사전 📖 【免费下载链接】tech-interview-for-developer 项目地址: https://gitcode.com/GitHub_Trending/te/tech-interview-for-developer

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值