JAVA設計模式之觀察者模式(Observer)
阿新 • • 發佈:2021-01-30
觀察者模式
一種行為型模式,當物件間存在一對多的對應關係時,並且有需要將通知傳送給所有的依賴物件,這時可以採用觀察者模式。
- 優點
- 1、耦合度低
- 2、有一套相應的觸發機制
- 缺點
- 1、如果一個被觀察者物件有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間。
- 2、如果在觀察者和觀察目標之間有迴圈依賴的話,觀察目標會觸發它們之間進行迴圈呼叫,可能導致系統崩潰。
程式碼展示
- 定義介面
/** *觀察者 */ public interface Observer { //處理訊息 public void handle(String message)
- 編寫實現
/** * 觀察者實現 */ public class DefaultObserver implements Observer { @Override public void handle(String message) { System.
- 程式碼測試
@Test public void test_observer(){ Subject subject = new DefaultSubject(); subject.attach(new DefaultObserver()); subject.attach(new DefaultObserver()); subject.attach(new DefaultObserver()); subject.attach(new DefaultObserver()); subject.attach(new DefaultObserver()); subject.nodifyObservers("observer pattern test"); }
- 測試結果
observer pattern test: main observer pattern test: main observer pattern test: main observer pattern test: main observer pattern test: main
- 改進措施
以上的notifyObservers方法通知所有的觀察者時,採用的同步的方式處理的,上文已說到,此種同步方式可能會導致系統性能問題,或者有一個出現問題時,會導致其他的觀察者通知不到。那麼,我們做如下改造:- Code
/** * 非同步處理主題類 */ public class AsyncSubject implements Subject { private List<Observer> observers = new ArrayList<>(); ExecutorService service = Executors.newFixedThreadPool(10); @Override public void nodifyObservers(String message) { // for (Observer ob : observers) { // service.submit(new Runnable() { // @Override // public void run() { // ob.handle(message); // } // }); // } observers.forEach((ob) ->{service.submit(() -> ob.handle(message));}); } @Override public void attach(Observer ob) { this.observers.add(ob); } }
- 測試Code
@Test public void test_observer(){ Subject subject = new AsyncSubject(); subject.attach(new DefaultObserver()); subject.attach(new DefaultObserver()); subject.attach(new DefaultObserver()); subject.attach(new DefaultObserver()); subject.attach(new DefaultObserver()); subject.nodifyObservers("observer pattern test"); }
- 測試結果
observer pattern test: pool-1-thread-1 observer pattern test: pool-1-thread-2 observer pattern test: pool-1-thread-3 observer pattern test: pool-1-thread-4 observer pattern test: pool-1-thread-5
通過引入執行緒池的方式來解決同步中可能存在的問題,Spring中的多播器也是一樣的原理,有興趣的同學,可以研究研究。