C#とRxでリアクティブプログラミングしてみた。
※ C#初心者なので、コードで至らない点ありましたコメント頂けたら助かります。
なんだそれ
Rx
Reactive Extensionsというライブラリ。
簡単に紹介すると、Linqライクな構文を持つ 特定のシーケンス の管理が出来るもの (と認識している。)
詳細はググって下さい。
リアクティブプログラミング
結構、抽象的な概念だったりするので、私からの説明は割愛。
RP(Reactive Programming) や FRP(Functional Reactive Programming)
などがあります。
それを区分けするには、未だ理解度が足りない。
詳細はググって下さい。
開発環境の準備
私が使用している端末はMacなので Xamarin Studio というIDEを使う事にしました。
VisualStudio や MonoDevelopなどでも同様な事が出来ると思います。
C#のコンソールアプリケーションを作り、add packagesからズドンと
Reactive Extesions - Main Library
を突っ込みます。
早速コードを書こう。
シーケンス管理と言う事で、 私の休日のシーケンスを、リアクティブプログラミングで表現しました。
ドスン
using System;
using System.Collections.Generic;
using System.Reactive.Linq;
namespace Rx
{
// ステータス管理型
using StateMap = Dictionary<string, Dictionary<string, Action>>;
class MainClass
{
public static void Main (string[] ars)
{
// ステータス定義
const string AWAKE = "AWAKE";
const string EAT = "EAT";
const string NET_SURFIN = "NET_SURFIN";
const string SLEEP = "SLEEP";
// ステータス上で使われる、呼び出し関数の想定
const string ON_ENTER = "onEnter";
const string UPDATE = "update";
const string ON_EXIT = "onExit";
var stateMap = new StateMap ();
// 初期化用delegate、仮でステート名と呼び出し関数名を表示する。
// Updateでsleepをしているのは、処理してる雰囲気出すため。意味は無い。
Action<string, StateMap> stateInit = delegate(string stateStr, StateMap obj) {
var action = new Dictionary<string, Action>();
action.Add(ON_ENTER, () => Console.WriteLine(stateStr + ":" + ON_ENTER));
action.Add(ON_EXIT, () => Console.WriteLine(stateStr + ":" + ON_EXIT));
action.Add(UPDATE, delegate {
Console.WriteLine(stateStr + ":" + UPDATE);
System.Threading.Thread.Sleep (1000);
});
obj.Add(stateStr, action);
};
// 各種ステートで実際に初期化
stateInit (AWAKE , stateMap);
stateInit (EAT , stateMap);
stateInit (NET_SURFIN, stateMap);
stateInit (SLEEP , stateMap);
// Rxにステート毎のシーケンスを登録します。
IObservable<Action> provider = Observable.Create<Action> (obj => {
foreach (var state in stateMap) {
obj.OnNext (() => state.Value[ON_ENTER]());
obj.OnNext (() => state.Value[UPDATE]());
obj.OnNext (() => state.Value[ON_EXIT]());
}
obj.OnNext (() => Console.WriteLine ("all sequence success."));
obj.OnCompleted ();
return System.Reactive.Disposables.Disposable.Empty;
});
// 実行!
provider.Subscribe (sequence => sequence ());
}
}
}
AWAKE:onEnter
AWAKE:update
AWAKE:onExit
EAT:onEnter
EAT:update
EAT:onExit
NET_SURFIN:onEnter
NET_SURFIN:update
NET_SURFIN:onExit
SLEEP:onEnter
SLEEP:update
SLEEP:onExit
all sequence success.
何故か、哀しくなりますね。
こういう使い方が正しいのかどうか分かりませんが、ステートマシンの代わりになるってだけで良いのではないでしょうか。
まだ試していませんが、各種EventやwebAPIの通信などでも、Rxを使えば 一つのシーケンスとして 実装が出来るそうです。
すごい。
脱・コールバックネスト地獄!
勉強中なので今回はここまで。
Author And Source
この問題について(C#とRxでリアクティブプログラミングしてみた。), 我々は、より多くの情報をここで見つけました https://qiita.com/dotKomu/items/198d43d63eab08b2fafb著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .