iT邦幫忙

2021 iThome 鐵人賽

DAY 4
0
Software Development

從零開始Reactive Programming- Spring系列 第 5

[Day 4] Reactive Programming - 觀察者模式Observer Pattern

https://refactoring.guru/design-patterns/observer

圖片來源

前言

Reactive Programming 概念上與Observer Pattern非常相似,先來了解這個Design Pattern。

Observer Pattern

Observer Pattern 會有兩種角色,一種是subject主體,是我們感興趣的目標,另一種是observers觀察者,觀察者選擇了各種感興趣的主題去關注,當主題的狀態發生變化的時候就會通知觀察者。

生活中有很多例子,以前的送報紙,訂報紙的人就是觀察者,想了解新聞,所以報紙就會派發到家裡。Youtube或是Twitch上的訂閱制,使用者就是觀察者,對哪一個實況主或是頻道有興趣,就點選訂閱,當實況主開啟直播、Youtuber發布新影片,就會有通知送達使用者,如果不使用Observer Pattern,使用者如果想要知道有沒有新影片,就必須要時不時的去查看是否有更新,這還是用電腦,如果是想去看店家缺貨已久的PS5遊戲機是否已到貨,若沒有觀察者模式可以訂閱通知,則必須要出家門到店裡面才能得知。
https://ithelp.ithome.com.tw/upload/images/20210918/20141418BngyS5sDZD.png

DEMO

實際設計一個簡單的例子
Subject與Observer的Interface,定義出基本的訂閱、取消訂閱、通知與更新的方法。

public interface Subject { 
  void subscribe(Observer observer); 
  void unsubscribe(Observer observer); 
  void notifyObservers(); 
}
public interface Observer { 
  void update(String name); 
}

實作使用者與YotubeChannel類別,更新狀態印出頻道名稱。頻道紀錄訂閱者與頻道名稱,訂閱決定是否放入訂閱者名單當中,更新時會通知所有訂閱者。

public class User implements Observer{ 
  @Override 
  public void update(String name) { 
    System.out.println(name + "更新囉"); 
  } 
}
@Data 
@NoArgsConstructor 
public class YoutubeChannel implements Subject{ 
  private String name; 
  private List<Observer> users; 
  public YoutubeChannel(String name) { 
    this.name = name; 
    users  = new ArrayList<>(); 
  } 
  @Override 
  public void subscribe(Observer observer) { 
    users.add(observer); 
  } 
  @Override 
  public void unsubscribe(Observer observer) { 
    users.remove(observer); 
  } 
  @Override 
  public void notifyObservers() { 
    users.forEach(user -> user.update(name)); 
  } 
}

最後執行測試,創立一個User並訂閱兩個頻道,當兩個頻道更新時就可以看見通知,而取消訂閱CS50後就只會通知一個。

  @Test 
  void test() { 
    User user = new User(); 
    YoutubeChannel cs50 = new YoutubeChannel("CS50"); 
    YoutubeChannel springDevelop = new YoutubeChannel("SpringDevelop");

    cs50.subscribe(user); 
    springDevelop.subscribe(user);

    cs50.notifyObservers(); 
    springDevelop.notifyObservers();

    cs50.unsubscribe(user);

    cs50.notifyObservers(); 
    springDevelop.notifyObservers();

    /*
    output:
    CS50更新囉 
    SpringDevelop更新囉 
    SpringDevelop更新囉
    */
  }

結語

如果你已經了解Event-driven,應該會覺得十分熟悉,只是Event-driven通常中間會有一個Queue但是Observer Pattern則不一定。了解Observer Pattern之後下一篇就要開始真正進入Reactive Programming,會先從Java 9開始了解。

資料來源


上一篇
[Day 3] Reactive Programming - Functional Programming
下一篇
[Day 5] Reactive Programming - Java 9(Publisher、Subscribers)
系列文
從零開始Reactive Programming- Spring32

尚未有邦友留言

立即登入留言