iT邦幫忙

2022 iThome 鐵人賽

DAY 23
0

在C#中有一個強大的monad - IObservable,這個盒子包裝了一個要被觀察的物件,今天先簡介一下基本概念

觀察者-被觀察者

先觀察IObservable-IObserver這兩個界面還有簡易的範例

public interface IObservable<out T>
{
	// 準備讓被觀察者註冊訂閱的方法
	IDisposable Subscribe(IObserver<T> observer);
}

public interface IObserver<in T>
{
	// 觀察者接收到通知成功要做的事
    void OnNext(T value);

	// 觀察者接收到通知失敗要做的事
	void OnError(Exception error);

	// 全部的通知都收到要做的事情,非必要
	void OnCompleted();
}

// 實做IObservable與IObserver物件
public class Observable : IObserable<string> { /* todo */ }
public class Observer : IObserver<string> { /* todo */ }

// 建立被觀察的物件,Observable
IObservable<string> observable = new Observable();
// 建立觀察者物件
IObserver<string> observer = new Observer();

// 註冊訂閱
using var subscribe = observable.Subscribe(observer);
// 把方法組合起來
while (Console.ReadLine() is { } s && s != "q")
{
    try
    {
        observer.OnNext(s);
    }
    catch (Exception e)
    {
        observer.OnError(e);
    }
}

observer.OnCompleted();

IObservable-IObserver這兩個介面基本上已經把整個觀察者模式定義出來了,只是每次實做都要實做方法的內容,並沒有想像中的好用,索性我們有Rx.net這個套件,大大化簡了這個流程。

Observable Monad

是的,Monad又來了。首先要設計一個IObservable實例非常的麻煩,索性Rx.net幫我們預先準備了幾個方法,先從IObservalbe的一些特性開始

  1. IObservable內部包含了觀察值

    這不是廢話嗎?不然要觀察什麼,然而既然是觀察值就代表我們可以觀察單個或是多個值,Rx.net幫我們準備了幾個方法來製作IObservable實例

    • Observable.Return<T>(T value) : 就是Return,能夠將T的值包裝進Observable
    • IEnumerable<T>.ToObservable() : 可以是觀察多個值,IObservable具有IEnumerable的特性,兩者是可以互相轉換的
  2. IObservable內部包含了將來值

    我們需要觀察的值在當下是未知的,所以

    • Task<T>.ToObservable():Task<T>內部包含的也是將來值,所以兩者也是可以轉換的

訂閱事件

Rx.net將訂閱事件化簡,只需要

observable.Subscribe(onNext:x=>/*成功後要做的事情*/)

就可以達到需要結果。

小結

Rx.net還有一些強大的延伸功能,這邊就不特別詳談,明天探討IObservable的monad特性。


上一篇
Day22. Query-Expression Pattern
下一篇
Day24. Rx(2)
系列文
Functional Programming with C#30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言