Java反應式程式設計(1)

2022-11-14 09:04:19

您好,我是湘王,這是我的部落格園,歡迎您來,歡迎您再來~

 

前面把Java函數語言程式設計的由來和最主要的核心知識點講完了。包括比較難懂的Lambda表示式是怎麼演變而來的也全部都擼了一遍。Lambda表示式這種程式設計方式的確是讓人不太習慣,尤其是之前那種純物件導向程式設計的思維模式一旦建立起來之後,想要再接受這種比較奇怪的語法和程式設計模式,確實是非常困難。但Lambda表示式和流式程式設計的出現,又催生了另一門新的技術:反應式程式設計。

《三國演義》中說:「天下大勢,分久必合,合久必分」。在科技領域也是一樣。之前沒有科學的時候,由占星術、鍊金術、神學等催生出了一系列的自然科學,像什麼物理、化學、數學等等。等到這些學科演變的差不多了之後,又開始了逐步的融合。

反應式程式設計就和這有點類似,它是融合了Lambda表示式、流式程式設計和觀察者模式的一種新的程式設計正規化。

就像很多反應式程式設計的技術書、官網和資料裡面說的,「一切皆是流」,比如我們其實無時不刻都在呼吸對吧,而且吸入和撥出的都是空氣,也就是氣流,這個很好理解哈~然後我們的嘴巴會去吃東西,就是食物吧,它也會變成食物流,其他的也是一樣,像我們看到的外部的風景啊、人物啊、抖音裡面的視訊啊,都是視覺流,還有我們和其他人之間的談話、聊天什麼的,都是語音流,而且這種視覺流和語音流很多都是持續的,源源不斷的。就像這樣:

 

 

 

而且這些流就是我們生活中每天都需要面對的各種各樣的事情,比如吃了東西,呼吸了新鮮空氣,就會讓我們獲得能量,就不會覺得餓或者沒力氣了,或者看到外面漂亮的風景,小哥哥小姐姐,以及美食,或者說和朋友談話、聊天之後就會覺得很愉快,就能引起心理和生理反應,或者說比如和誰一起吃工作餐談話,談的不愉快就直接結束,所以這裡有個紅叉叉,正常結束的話就是一個豎線,比如這段時間對吃的、帥哥美女、聊天或者抖音都沒啥興趣,走冷淡風,就不再對這些外部事件產生反應了,所謂的反應式程式設計裡面所說的反應,其實就是一種對行為的響應。

如果把程式碼想象成一個人的話,那麼那些外部的事情用計算機專業的話來說叫事件,比如使用者點選頁面按鈕傳送訊息、鍵盤輸入、物聯網裝置不斷地傳送訊號等等,都是各種輸入流,而且程式需要對這些各種事件都做出響應,或者反應,而且要及時。用以前的方式也是可以的,不過如果這種事件很多,涉及的執行緒、回撥就會很多,所以就需要一種新的程式設計方式來處理這種叫做mashup的混合式Web應用開發。關於反應式程式設計的一種正式的描述可以看反應式程式設計官方的《反應式宣言》:

 

 

 

剛才說的只是反應式程式設計一些概念性或者是感性的認識,真正要了解反應式程式設計,還是要看程式碼:

public static void main(String[] args) {

  Person person = new Person("zhangsan", 18);

  // 資料怎麼來就怎麼處理,處理完後就結束
  Observable.just("1", 2, true, 0.618, person, new String("haha"))
    .subscribe(System.out::println);

}

 

 

執行後可以看到,不管是什麼樣的資料型別,都會被just給展示出來,這就是「流」的概念。而在以前的Java集合List中,肯定是不可能有這種騷操作的。

這種程式碼範例其實在Reactive的Github官網上面有很多,可以開啟它的官網檢視:

 

 

 

剛才的程式碼裡面有三個特點:

1、出現了Lambda表示式System.out::println);

2、出現了流.just().subscribe());

3、出現了一個叫做Observable的類,而熟悉設計模式的都知道,它是觀察者模式中特有的一個類。

下面是觀察者模式的一個示意圖:

 

 

 

觀察者模式也是回撥實現的一種方式。觀察者模式在開發裡面還有另外一個「外號」:釋出-訂閱模式。經典的觀察者模式是像下面這樣的:

 

 

 

可以用程式碼來演示這種劇院和觀眾的觀察者模式:

// 觀眾的行為(觀察者-訂閱者介面)
@FunctionalInterface
interface Viewer {
  public void watch();
}

// 具體訂閱者
class ConcreteViewer implements Viewer {
  @Override
  public void watch() {
    System.out.println("正在看錶演");
  }
}
// 演員(釋出者)
class Actor {
  // 觀眾(訂閱者)列表
  private List<Viewer> viewers = new ArrayList<Viewer>();
  // 買票(訂閱)
  public void buyticket(Viewer viewer) {
    viewers.add(viewer);
  }
  // 退票(取消訂閱)
  public void refund(Viewer viewer) {
    viewers.remove(viewer);
  }
  // 開始表演
  public void play() {
    for (Viewer viewer : viewers) {
      viewer.watch();
    }
  }
}

/**
 * 劇院
 *
 * @author 湘王
 */
public class Theater {
  public static void main(String[] args) {
    ConcreteViewer viewer1 = new ConcreteViewer();
    ConcreteViewer viewer2 = new ConcreteViewer();
    Actor actor = new Actor();
    actor.buyticket(viewer1);
    actor.buyticket(viewer2);
    actor.buyticket(() -> System.out.println("正在VIP包廂看錶演"));
    actor.play();
  }
}

 

 

這也是反應式程式設計的門檻比較高的原因,對於一些沒有學過設計模式的同學來說,反應式程式設計確實很不好理解。這也沒辦法,因為整個反應式程式設計的根基就是建立在觀察者模式之上的,而且還結合Java9裡面的Flow API做了一些改變,有興趣的同學可以自己去了解一下,所以總結來說的話,反應式程式設計的特點就是這樣的:

 

 

 

用一句簡單的話來概括反應式程式設計 = 函數語言程式設計 + 流式計算 + 觀察者模式。

 

 


 

 

感謝您的大駕光臨!諮詢技術、產品、運營和管理相關問題,請關注後留言。歡迎騷擾,不勝榮幸~