代码界的「吃瓜群众」:观察者模式的八卦艺术

78 阅读3分钟

代码界的「吃瓜群众」:观察者模式的八卦艺术


一、当对象开始「追星」

你是否见过这样的场景?
气象局的温度计打个喷嚏(数据变化),手机天气APP、电子广告牌、智能空调就集体擤鼻涕(更新状态);
微博热搜榜稍有风吹草动,百万吃瓜群众瞬间涌入评论区...

这就是观察者模式的魅力——让代码学会「八卦」,当一个对象状态改变时,所有暗恋它的对象都会收到爱的信号!


二、狗仔队与明星的契约(UML图)

   ┌─────────────┐          ┌─────────────┐
   │  Subject    │          │  Observer   │
   ├─────────────┤          ├─────────────┤
   │ +attach()   │<───────┐ │ +update()   │
   │ +detach()   │        ├─┼─────────────┤
   │ +notify()   │        │ └─────────────┘
   └──────△─────┘        │
          │                 │
   ┌──────┴──────┐    ┌─────┴─────┐
   │  Concrete   │    │ Concrete  │
   │  Subject    │    │ Observer  │
   └─────────────┘    └───────────┘
  • 明星(Subject):被观察的对象(比如微博热搜)
  • 狗仔队(Observer):观察者接口(定义偷拍规范)
  • 站姐(ConcreteObserver):具体的吃瓜群众
  • 私生饭(ConcreteSubject):具体的被八卦对象

三、娱乐圈的代码狂欢(场景实战)

1. 创建顶流明星(被观察者)
public class Celebrity {
    private String name;
    private String latestGossip;
    private List<Fan> fans = new ArrayList<>(); // 粉丝后援会

    public Celebrity(String name) {
        this.name = name;
    }

    // 官宣新瓜(推模型)
    public void releaseGossip(String gossip) {
        this.latestGossip = gossip;
        notifyFans("【推送】" + name + "最新动态:" + gossip);
    }

    // 私生饭注册
    public void addFan(Fan fan) {
        fans.add(fan);
    }

    // 脱粉处理
    public void removeFan(Fan fan) {
        fans.remove(fan);
    }

    // 全网推送
    private void notifyFans(String message) {
        for (Fan fan : fans) {
            fan.update(message);
        }
    }
}
2. 创建吃瓜群众(观察者)
public interface Fan {
    void update(String message); // 接收瓜的信号
}

// 普通吃瓜群众
class NormalFan implements Fan {
    private String name;

    public NormalFan(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + "的手机震动:叮!" + message);
    }
}

// 职业狗仔队
class Paparazzi implements Fan {
    @Override
    public void update(String message) {
        System.out.println("狗仔队打开摄像机:" + message + "(开始编故事...)");
    }
}
3. 娱乐圈风云突变
public class EntertainmentCircle {
    public static void main(String[] args) {
        // 创建顶流明星
        Celebrity kunkun = new Celebrity("鸽鸽");
        
        // 培养粉丝群体
        Fan fan1 = new NormalFan("小黑子");
        Fan fan2 = new NormalFan("真爱粉");
        Fan fan3 = new Paparazzi();

        // 粉丝关注明星
        kunkun.addFan(fan1);
        kunkun.addFan(fan2);
        kunkun.addFan(fan3);

        // 明星搞事情!
        kunkun.releaseGossip("练习时长两年半!");
        kunkun.releaseGossip("发布新歌《鸡你太美》");
        
        // 小黑子脱粉
        kunkun.removeFan(fan1);
        kunkun.releaseGossip("宣布退役篮球界"); // 小黑子收不到通知
    }
}

四、观察者 vs 狗仔队:推瓜与扒瓜的区别

维度观察者模式普通轮询
主动权明星主动推送粉丝不断打电话问
实时性即时通知(光速吃瓜)延迟(可能错过热搜)
资源消耗按需推送(节能模式)持续消耗(费电费流量)
代码耦合松耦合(明星不认识粉丝)强耦合(粉丝跟踪明星)
现实类比微博推送通知手动刷新网页

五、代码世界的八卦网络

  1. Java Swing:按钮点击事件监听(你的每个点击都被暗中观察)
  2. Spring事件机制ApplicationEventPublisher广播系统消息
  3. ReactiveX:响应式编程的核心观察者模型
  4. GUI框架:MVC架构中的数据绑定
  5. 电商系统:商品降价时通知所有收藏用户

冷知识
Java曾经提供java.util.Observable类,但在Java 9被标记为废弃——因为现代框架有更好的实现方式!


六、防塌房编码指南

  1. 防止内存泄漏

    // 粉丝脱粉时要及时remove
    // 否则明星过气后粉丝列表仍占用内存
    
  2. 避免循环通知

    // A通知B,B又通知A
    // 会导致代码陷入死亡循环
    
  3. 线程安全处理

    // 用CopyOnWriteArrayList代替普通List
    // 防止遍历时修改粉丝列表
    
  4. 支持异步通知

    // 用ExecutorService实现异步推送
    // 避免阻塞明星线程
    
  5. 消息分级处理

    // 给消息打标签(普通消息/紧急通知)
    // 让粉丝决定是否处理
    

七、娱乐圈生存总结

观察者模式就像代码界的八卦传播链:

  • :用于一对多的依赖关系
  • :保持主题与观察者的解耦
  • 不要:让观察者处理耗时操作
  • 不要:忘记取消注册观察者

当你在朋友圈看到小红点时,请想起观察者模式——那个让你永远逃不过点赞命运的神秘力量!