首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 雙向觀察者模式:雙聯動下拉框解耦實現

     編輯:程式設計綜合問答

場景

Class A 有字段 a1、a2;Class B 有 b1、b2。
a1 變化 → 影響 b1;b2 變化 → 影響 a2。雙向依賴,需解耦。

核心模式:事件總線 / 中介者

**雙方不直接持有引用**,通過中介者註冊/發布事件。

// 事件定義
class A1ChangedEvent { public final String newValue; ... }
class B2ChangedEvent { public final int newValue; ... }

// 中介者 (單例或依賴注入)
class Mediator {
    private final List> subscribers = new CopyOnWriteArrayList<>();
    public void subscribe(Consumer handler) { subscribers.add(handler); }
    public void publish(Event event) { subscribers.forEach(h -> h.accept(event)); }
}

// A 類
class A {
    private String a1;
    private final Mediator mediator;
    public A(Mediator m) { this.mediator = m; 
        m.subscribe(e -> { if (e instanceof B2ChangedEvent) this.a2 = computeA2(e); });
    }
    public void setA1(String v) { 
        this.a1 = v; 
        mediator.publish(new A1ChangedEvent(v)); 
    }
}

// B 類
class B {
    private int b2;
    private final Mediator mediator;
    public B(Mediator m) { this.mediator = m;
        m.subscribe(e -> { if (e instanceof A1ChangedEvent) this.b1 = computeB1(e); });
    }
    public void setB2(int v) { 
        this.b2 = v; 
        mediator.publish(new B2ChangedEvent(v)); 
    }
}

優點

  • **完全解耦**:A、B 無相互引用,可獨立測試、替換。
  • **擴展性強**:新增 C 類只需訂閱事件,不修改 A/B。
  • **線程安全**:CopyOnWriteArrayList 或 RxJava/Reactor 流式處理。

對比:直接引用 (強耦合)

// 不推薦
class A { B b; void setA1() { b.onA1Change(); } }
class B { A a; void setB2() { a.onB2Change(); } }
// 循環依賴、難測試、死鎖風險

框架支持

  • Guava EventBus:eventBus.register(this) + @Subscribe 註解。
  • Spring ApplicationEvent:applicationContext.publishEvent() + @EventListener。
  • RxJava/RxJS:PublishSubject 熱流,支持背壓、操作符組合。

最佳實踐建議

  1. 定義清晰的**事件對象** (POJO/Record),包含足夠上下文信息。
  2. 避免事件風暴:合併高頻變更、使用防抖/節流。
  3. 文檔化事件契約:命名規范 DomainActionEvent (如 OrderCreatedEvent)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved