コンテンツにスキップ

英文维基 | 中文维基 | 日文维基 | 草榴社区

Observable (プログラミング)

出典: フリー百科事典『ウィキペディア(Wikipedia)』

Observable(オブザーバブル)とは、プログラミングにおいて非同期処理やストリーム処理を扱うためのデザインパターンの一つであり、データの変化やイベントの発生を購読者(オブザーバーやサブスクライバー)に通知する仕組みを提供する。主にリアクティブプログラミングやイベント駆動型アーキテクチャにおいて重要な役割を果たし、データのストリームをリアルタイムで処理する際に用いられる[1][2]

Observableは、オブザーバーパターンに基づいて構築されており、購読(サブスクリプション)を通じてデータやイベントの変化を購読者(オブザーバーやサブスクライバー)に通知する仕組みを提供する。この仕組みはリアクティブプログラミングの中核を成し、非同期で継続的なデータストリームを効率的に処理するために、マップ、フィルタ、リデュースなど様々なオペレーターを備えている。

プログラミング言語毎にObservableの実装は異なり、PythonJavaJavaScriptC#などの言語において特定のライブラリやフレームワークを通じて実現されている。例えば、RxPY[3][4]、RxJava[1][5]、RxJS[6][7].NET[2][8]のObservableが代表的な実装例である。これらの実装では、データのシークエンスを非同期で処理し、エラー処理やメモリ管理の機能も備えている。

ObservableはWebアプリケーションのデータストリーミングやリアクティブプログラミング[1][9]マイクロサービス間の非同期通信[1][10]ゲーム開発[11][12]など、幅広い分野で応用されている。特に非同期処理においては、スケーラビリティやパフォーマンス向上のために有用であるが、その一方でデバッグの難しさや学習曲線の高さなどの課題も存在する。

また、Observableはプロミスフューチャーといった他の非同期プログラミングモデルと比較されることが多く、それぞれの技術との違いや利点を理解することで、適切な選択が可能となる[1][2]。Observableの進化は、リアクティブプログラミングの発展と共に続いており、現在も様々な分野で利用され続けている。

このページでは、Observableの基本概念、構造、実装、応用例、利点と欠点、関連技術、そして歴史と発展について詳述する。

序論

[編集]

概要

[編集]

Observableとは、非同期処理を効率的に扱うためのプログラミング手法であり、主にリアクティブプログラミングやイベント駆動型プログラミングで使用される[1][6]。Observableを利用することで、データのストリームや連続的なイベントの発生を購読し、それらの結果をリアルタイムで通知することができる。この仕組みにより、動的で応答性の高いアプリケーションを容易に開発することが可能となり、非同期処理を統一的かつ柔軟に管理できるようになる。

なお、Observableに対して購読を行うオブジェクトの呼称は、Observableが組み込まれるプログラミングパラダイムに左右される[1][13][14][15]。例えば、オブザーバーパターンにおいて購読を行うオブジェクトはオブザーバー(Observer)と呼ばれ[16][17]パブリッシュ/サブスクライブパターン[18][19]サブスクリプションパターン[13][20]、リアクティブプログラミング[1][13]の文脈ではサブスクライバー(Subscriber)と呼ばれることが多い。また、イベント駆動型プログラミングではリスナー(Listener)という用語が用いられることもあり[18][21]、さらにデータフローやストリーム処理の文脈で、データを消費する役割をもつ購読者はコンシューマー(Consumer)と呼ばれることもある[22][23]。これらの呼称は、使用されるフレームワークやライブラリ、プログラミングパラダイムに依存しており、似た購読機構であっても文脈に応じて異なる呼称が使われる。

背景と歴史

[編集]

Observableの概念は、オブザーバーパターンに基づいており、特に非同期処理の複雑さを軽減するために発展してきた[1][13]。オブザーバーパターン自体は、ソフトウェアデザインパターンとして広く認識されており、特定のイベントやデータの変化を監視するための手段として長年使用されてきた。

オブザーバーパターンは1994年に発表された『Design Patterns: Elements of Reusable Object-Oriented Software[16][24]』(通称GoF本[注釈 1])で公式に紹介されたデザインパターンの一つである。このパターンは、特定のオブジェクトが状態の変化を複数のオブザーバーに通知する仕組みを提供する。GoF本の登場以前からオブザーバーパターンに類似する手法は存在していたが、この書籍により、オブジェクト指向プログラミングにおける設計の基本要素として広く認知されるようになった。オブザーバーパターンの導入によって、オブジェクト間の依存関係を緩和し、システム全体の拡張性保守性が向上することが期待された。このパターンは特にGUI(グラフィカルユーザーインターフェース)やイベント駆動型のシステムにおいて非常に有効であり、ユーザーインターフェースのイベントを効率的に管理するための基本的な設計手法となっている。

リアクティブプログラミングの台頭により、Observableはより広範な関心を集めるようになり、様々なプログラミング言語やフレームワークで実装されるようになった[1][13][14][31]。Observableの概念は、JavaやC#など多くの言語で早期に取り入れられ、特にJavaでは1995年の初期バージョンからjava.util.Observableクラスが標準APIとして提供され[21][32]、C#では2002年にリリースされた.NET Framework 1.0でIObservable<T>インターフェースが導入された[33][34]。これにより、両言語において非同期処理やイベントの監視を効率的に行う仕組みが整備され、開発者は早い段階からObservableを活用したリアクティブ(敏感)なプログラムを構築できるようになった。この時期から開発者はオブザーバーパターンを手軽に実装できるようになったが、これらの初期実装には柔軟性やパフォーマンス面での課題も存在していた[21][32][35][36]

その後、リアクティブプログラミングの発展と共に、Observableは非同期処理やデータストリームの管理を強化する形で進化を遂げた[1][13][14][31]。特に、Reactive Extensions(リアクティブエクステンション、Rx)の登場により、Observableは非同期ストリーム処理の中核を担う存在となった。Rxは.NET向けに初めて開発されたライブラリで、非同期データストリームの処理を容易にするための豊富なオペレーター(マップ、フィルタ、リデュースなど)を提供し、これによりデータの変化やイベントをリアルタイムで処理するための効率的な方法が確立された。この技術は、後にJavaやJavaScriptなど他の多くの言語にも移植され、現代の非同期プログラミングの重要なコンポーネントとして確立された。特にRxJSなどのライブラリは、フロントエンド開発においても広く使われており、Angularなどのフレームワークで公式に採用されている。こうした進化は、現代のアプリケーションが求める高いリアクティブ性(敏感さ)やスケーラビリティに対応する重要な技術として位置付けられている。

基本概念

[編集]

Observableとは

[編集]

Observableとは、データストリームやイベントの連続的な発生を監視し、購読者(オブザーバーやサブスクライバー)にリアルタイムで通知を行うためのプログラミング手法である[1][6]。Observableを使用することで、データフローを直感的かつ宣言的に表現でき、複雑な非同期処理をシンプルに管理できる。購読したオブザーバー(またはサブスクライバー、他)は、データの発行元であるObservableから通知を受け取り、それに応じた非同期処理を適切に実行する。

イベント駆動プログラミングにおける役割

[編集]

イベント駆動プログラミングでは、ユーザーの操作やシステムイベントに応じて処理が実行される[1][2]。Observableは、このイベント駆動型の環境において、イベントの発生と処理の流れを効率的に管理するためのツールとして重要な役割を果たす。例えば、ユーザーインターフェースのイベント(クリックや入力)を監視し、それに応じてリアルタイムで処理を行うことができる。また、データストリームを利用することで、動的なデータの更新にも対応できる。

他の非同期プログラミングモデルとの比較

[編集]

Observableは、プロミスフューチャーなどの他の非同期プログラミングモデルと比較されることが多い[1][37]。プロミスは単一の非同期処理の結果を扱うのに対し、Observableは複数のイベントやデータストリームを扱うことができる点で異なる。また、プロミスは一度解決されるとその後の値の変化には対応できないが、Observableは継続的にデータの更新やイベントの発生を監視し続けることができる。これにより、リアクティブプログラミングのニーズに対してより柔軟に対応できる。フューチャーは、プロミスと似た概念であるが、主に並行処理や並列処理の文脈で使用される。Observableは、これらのモデルと比較して、イベントドリブンな非同期処理に特化している点が特徴である。

Observableの構造

[編集]

サブスクリプション

[編集]

Observableの基本構造において、サブスクリプションは重要な要素である[1][6]。サブスクリプションとは、Observableに対して購読者(オブザーバーやサブスクライバー)が登録され、データやイベントの通知を受け取るプロセスを指す。購読者は、Observableから発行される値やイベントを受け取り、これに基づいて指定された処理を実行する。サブスクリプションは、Observableのライフサイクルを管理し、必要に応じて購読(サブスクリプション)を解除することでリソースの管理も行う。

オブザーバーパターン

[編集]

Observableは、オブザーバーパターンに基づいて設計されている[1][2]。従来のオブザーバーパターンにおいては、通知の発行元はサブジェクトと呼ばれる。このデザインパターンは、サブジェクトが状態の変化やイベントを発行し、その変化を他のオブジェクト(オブザーバー)に通知する仕組みをもつ。オブザーバーは、サブジェクトに購読(サブスクライブ)することで、状態の変化に対する通知を受け取る。オブザーバーパターンは、イベント駆動型プログラミングの基本的な構成要素であり、Observableを用いた非同期処理においてもその基盤として機能している。主にリアクティブプログラミングやイベント駆動型アーキテクチャにおいて、Observableは非同期データストリームの発行元として機能し、従来のオブザーバーパターンにおけるサブジェクトの役割を拡張して担っている。特にリアクティブプログラミングにおけるサブジェクトは、Observableの一種として機能し、データを発行するだけでなく、他のObservableを購読することもできるため、双方向の役割をもつ。

オペレーター(マップ、フィルター、リデュース等)

[編集]

Observableの強力な特徴の一つは、データストリームを効率的かつ柔軟に処理するために、豊富なオペレーターが提供されている点である[1][6]。これらのオペレーターを使用することで、ストリーム内のデータを変換、フィルタリング、集約し、複雑な非同期処理を簡潔に行うことができる。例えば、マップ(map)オペレーターは各データ要素を変換し、新しい形に変換されたデータストリームを生成する。これにより、元のデータを保持しつつ、計算や変換を施した結果をストリームとして流すことができる。フィルター(filter)オペレーターは、特定の条件に合致するデータのみを抽出し、不要なデータをストリームから除外する役割をもつ。これにより、関心のあるデータのみを効率的に処理できるようになる。さらに、リデュース(reduce)オペレーターは、データストリーム全体を集約し、単一の結果を生成する。これは、例えば数値の合計や平均、またはオブジェクトの集合を一つにまとめる際に使用される。このようなオペレーターを組み合わせることで、データの流れを直感的に制御し、リアクティブプログラミングにおける複雑な非同期処理やデータ処理を効率的に行うことができる。これにより、開発者はデータストリームを視覚的に捉え、シンプルかつ強力な処理を行うことが可能となる。

ストリームとデータフロー

[編集]

Observableは、データストリームの概念に基づいており、このデータストリームとは、連続的に発生するデータやイベントの流れを指している[1][14][22][31]。データストリームは、固定的なデータセットとは異なり、時間の経過と共に新たなデータやイベントが発生し続けるという特徴をもつ。つまり、データストリームは、静的なデータではなく、動的に変化するデータの流れを表しており、リアルタイムで発生するデータの一連の流れを処理するためのモデルとなっている。Observableは、このデータストリームを監視し、各データやイベントの発生をキャッチして購読者(オブザーバーやサブスクライバー)に通知する役割を果たす。

データストリームは、時間軸に沿って次々と流れてくるデータやイベントの発生を処理するための基本的な枠組みとなっており、これに基づく非同期処理を容易にする[1][13][14][22]。Observableを用いることで、時間の経過に伴って発生するデータをリアルタイムで監視し、オペレーターと呼ばれる関数を通じてデータに対する変換やフィルタリング、集約といった処理を施すことができる。例えば、データストリーム内の各要素に対してマップオペレーターを適用してデータを変換し、フィルターオペレーターを使用して特定の条件に合致するデータのみを抽出することができる。このように、データストリームに対する処理は非常に柔軟に行える。

データフローの概念は、データストリームに対して適用されるオペレーターがデータをどのように変換し、その変換されたデータがどのように購読者に提供されるかを示している[7][14][22][38]。データフローは、データの発生元から購読者に至るまでの全体的な処理の流れを視覚的かつ直感的に把握できるため、非同期処理やイベント駆動型プログラミングにおける重要な設計要素となっている。これにより、複雑な非同期処理をより簡潔にモデル化し、処理の流れを管理することができる。

ストリームとデータフローの概念は、リアクティブプログラミングにおいて不可欠な要素であり、リアクティブシステムにおける動的なデータ処理を可能にする[1][13][14][31]。リアクティブプログラミングは、データの変化に即座に反応するシステムを構築するためのアプローチであり、特に複雑な非同期処理を効率的に表現するために、このストリームとデータフローの概念を活用している。Observableを利用することで、開発者は非同期処理の複雑さをシンプルに表現し、リアルタイムのデータ処理を効率よく行うことができる。このように、データストリームとデータフローは、現代のアプリケーションが求める応答性の高いシステムを構築するための基盤として機能している。

ColdとHot Observable

[編集]

Cold Observable(コールドオブザーバブル)とHot Observable(ホットオブザーバブル)は、Observableがデータを発行するタイミングやその性質に基づいた分類である。これらの違いは、データストリームの発行元がどのように動作し、購読者(オブザーバーやサブスクライバー)がそのストリームをどのように受け取るかに関係している。

Cold Observable

[編集]

Cold Observableは、購読者が購読を開始した時点で初めてデータの発行が開始されるObservableであり、これはデータストリームの発行を遅延させるという特性をもっている[1][7][13][14]。具体的には、Cold Observableは購読者が存在しない限り、データやイベントを発行することはない。購読者がObservableにサブスクライブすることで、初めてデータストリームが生成され、そのストリーム内のデータやイベントが購読者に向けて発行される。このため、購読者はいつでも同じデータストリームの「開始」から受け取ることができ、各購読者が同じデータの流れを独立して最初から取得する特徴がある。

Cold Observableは、「データの発行を引き起こす」という性質をもっているため、購読者がObservableにアクセスした瞬間に、データの流れやイベントがトリガーされる[1][7][13][14]。例えば、HTTPリクエストやファイル読み込みのような処理は典型的なCold Observableの例であり、各購読者がそれぞれのタイミングで購読を開始する度に、新たなリクエストやファイル読み込みが行われる。このため、複数の購読者が同じCold Observableを購読した場合、各購読者は個別のデータストリームを取得することになる。

この特徴をもつCold Observableは、特に以下のようなシナリオで使用される。

  • APIリクエスト:各購読者がAPIにリクエストを送信し、データを取得する際に、Cold Observableを利用することで、各購読者は独立したリクエストとレスポンスを受け取ることができる。例えば、二人のユーザーが同じAPIエンドポイントを購読した場合、各ユーザーの購読は個別のAPIリクエストを発行し、それぞれ独自のレスポンスを受け取る。
  • ファイル読み込み:複数の購読者が同じファイルを読み込む際、各購読者が独自にファイルを最初から読み込むように処理される。購読者がObservableをサブスクライブする度に、新たにファイルの読み込みプロセスが開始され、データが提供される。

また、Cold Observableは、データやイベントが一度発生した後にそれが再利用されることはなく、各購読者がそれぞれ新しいストリームを最初から開始する[1][7][13][14]。この性質は、リアルタイム性よりも、再現可能な結果や独立したデータストリームが重要なシナリオにおいて非常に有用である。例えば、同じデータセットやAPIレスポンスを複数の購読者が分析する場合、それぞれの購読者は個別にデータの流れを管理し、必要に応じたタイミングで同じプロセスを再現することができる。

Hot Observable

[編集]

Hot Observableは、購読者の有無にかかわらず、データを継続的に発行し続けるObservableであり、常に動作しているデータソースからデータが流れ続ける[1][7][13][14]。つまり、Hot Observableは外部のデータソースと直接結び付いており、購読者がストリームに接続する前から既にデータの発行が始まっている。このため、新たに購読を開始した場合、購読者はストリームの途中からデータを受け取ることになり、過去に発行されたデータやイベントは再度取得することができない。これは、購読者が接続するタイミングによって、受け取るデータが異なる場合があり、ストリームに早く接続すればするほど、より多くのデータを受け取ることができるが、遅れて接続した場合、既に流れてしまったデータを受け取ることはできないことを意味する。

Hot Observableは、既に動作している「既存のデータソースに接続する」性質をもっており、これはストリームが購読者の存在に依存せずにデータを流し続けることを意味する[1][13][14][31]。この種のObservableは、常時発生するデータを処理するシステムや、リアルタイム性が重要なシナリオで特に有効である。例えば、リアルタイムで発生するイベントやセンサーデータなど、購読者が接続していなくてもデータが生成され続けるようなシナリオでHot Observableは効果的に機能する。

Hot Observableでは、購読者が接続するとその時点からのストリームの進行状況に応じたデータを流し始め、ストリームの開始時点からのデータを流すCold Observableと異なる点が強調される[1][7][13][14]。Hot Observableは、データストリームが既に動作中であり、そのデータをリアルタイムで処理したいシナリオに適している。この性質により、購読者はストリームの途中で接続したり、ストリームの終了直前に接続したりすることができ、その結果、異なるデータやイベントを受け取ることになる。

例えば、マウスの移動イベントのようなユーザーインターフェースのリアルタイムな操作において、Hot Observableは各マウスの移動を継続的に監視し、購読者が接続した時点から、その後のマウスの動きのみを通知する[1][7][13][31]。このため、購読者は過去のマウス移動の情報は取得できず、購読を開始する前に既に発生していたイベントの情報には関知できない。同様に、株価のリアルタイムフィードもHot Observableの典型的な例であり、購読者はフィードに接続した時点からの株価の変動データを受け取り始めるが、購読前の株価情報は取得できない。

Hot Observableの具体的な特徴

[編集]
  • 継続的なデータ発行:購読者の有無に関係なく、ストリームはデータを発行し続ける。購読者がいなくても、データは流れ続ける。
  • 途中からの購読:購読者がいつストリームに接続しても、現在の状態からデータを受け取る。過去に流れたデータを再度取得することはできない。
  • リアルタイム性:リアルタイムのデータストリームを処理するのに適しており、センサーデータ、ユーザーイベント、リアルタイムの市場データなど、即時性が要求されるシナリオにおいて効果的である。

このように、Hot Observableは特にリアルタイムのデータ処理やイベント駆動型システムにおいて重要な役割を果たし、購読者がストリームに接続する前から既にデータの発行が行われているため、リアルタイムのデータを効率的に扱うことができる[1][13][14][31]。また、購読者の接続タイミングに応じて異なるデータを取得する性質をもつため、システムの応答性やスケーラビリティを高めることが可能である。

ColdとHot Observableの違いの要点

[編集]
  • Cold Observable:購読毎に新たなデータストリームを生成し、購読者は常に最初からストリームを受け取る。
  • Hot Observable:購読者が購読を開始する前からデータを発行しており、購読者はストリームの途中からデータを受け取る。

歴史的な背景

[編集]

概念的に見ると、Cold Observableの考え方が先に広く認知されていた[1][7][13][14]。Cold Observableは、購読者がストリームを開始するトリガーとなるモデルであり、非同期処理やイベント駆動プログラミングの初期から存在していた。これは、リクエストが発生した時点で新しいデータストリームが生成され、データの流れが購読者に対して提供されるというモデルである。このような考え方は、特に従来のプログラミングパラダイムにおいて一般的であり、HTTPリクエストやファイルの読み込みといった処理が典型的な例となる。これらの処理は、購読者毎に新しいリクエストを発行し、その結果を取得するというもので、各購読者が同じリソースにアクセスした場合でも、個別に独立したデータストリームが生成されることになる。

Cold Observableのこのモデルは、特にリクエスト/レスポンス型のデータ処理や、一度しか発生しない操作の処理に適しており、初期の非同期プログラミングやイベント駆動型プログラミングの基盤として使用されていた[1][7][13][14]。データが静的であり、明確なトリガーに基づいて発生する場合、このモデルは非常に有効であり、また従来の手続き型プログラミングの流れに適合していた。このため、Cold Observableの考え方は早期に確立され、一般的な非同期処理の手法として認知されていた。

一方で、Hot Observableの概念は、リアクティブプログラミングやリアルタイムデータストリームの需要が増加する中で、Cold Observableの後に明確化されてきた[1][13][14][31]。リアクティブプログラミングは、システムがデータの変化やイベントに即座に反応するというパラダイムであり、継続的なデータの流れやリアルタイム性が重要な役割を果たす。こうしたリアルタイムデータを扱うシステムにおいては、購読者の有無にかかわらずデータが発行され続ける必要があり、購読者が途中からストリームに参加した場合でも、現在の状態をリアルタイムで受け取ることが求められる。これに対応するために、Hot Observableの概念が明確に定義され、特にセンサーデータやリアルタイムイベント処理など、継続的かつ即時性の高いデータ処理の文脈で重要視されるようになった。

Hot Observableは、センサーデータや株価のフィードなど、常に発生し続けるデータストリームをリアルタイムで購読し、処理するシステムにおいて特に有用である[1][7][13][31]。このシナリオでは、購読者がストリームに途中から接続した場合、過去に発生したデータは取得できず、接続した時点以降に発生するデータのみが通知される。リアクティブプログラミングの普及と共に、このようなデータの扱いが重要視され、Hot Observableはリアルタイム性を求めるシステムの設計において欠かせない要素となっていった。

このように、Cold Observableが先に存在し、非同期処理やイベント駆動プログラミングの初期から使用されていた一方で、Hot Observableはより新しい技術として、リアクティブプログラミングの発展と共に、リアルタイムデータストリームの処理を効率化するために明確化された概念である[1][13][14][31]。技術の発展に伴い、リアルタイム性や即時性が要求されるシステムが増える中で、Hot Observableの重要性が高まってきた。

Observableの実装

[編集]

言語別の実装例

[編集]

Observableは、多くのプログラミング言語で利用可能であり、各言語に応じたライブラリやフレームワークが提供されている。これにより、異なるプラットフォームや開発環境でObservableを用いた非同期処理が実現できる。

Python(RxPY)

[編集]

RxPYは、PythonでのObservableの実装を提供するライブラリであり、RxJSと同様にリアクティブプログラミングをサポートする[3][4]。Pythonの非同期処理機能(asyncioなど)と組み合わせることで、イベント駆動型のシステムや、非同期データストリームの処理が可能となる。RxPYは、データ処理やリアルタイム分析、複雑なイベント処理など、様々な用途に使用されており、Pythonの柔軟なエコシステムと親和性が高い。

Java(RxJava)

[編集]

RxJavaは、Java向けのリアクティブプログラミングライブラリであり、Android開発やサーバーサイドアプリケーションの非同期処理に広く用いられている[1][5]。RxJavaは、複雑な非同期処理のフローを簡潔に表現できるため、バックグラウンドスレッドでの処理やユーザーインターフェーススレッドの処理などを効率的に管理できる。また、リアクティブ拡張としての豊富なオペレーターを備えており、データストリームの変換やフィルタリング、エラーハンドリングを柔軟に実装できる。

JavaScript(RxJS)

[編集]

RxJS(Reactive Extensions for JavaScript)は、JavaScriptでObservableを扱うためのライブラリであり、リアクティブプログラミングを容易にする[6][7]。RxJSでは、Observableを作成し、オペレーターを使用してデータストリームを変換・フィルタリングし、結果を購読者(オブザーバーやサブスクライバー)に通知する。非同期イベントの処理や、APIからのデータフェッチ、ユーザーインターフェースの応答処理などに広く利用される。JavaScriptはシングルスレッドで動作するため、RxJSのようなライブラリは非同期処理のパターンを整理し、コード可読性と保守性を高める役割を果たす。

C#(.NETのObservable)

[編集]

C#では、.NET Frameworkの一部としてObservableが提供されており、リアクティブプログラミングの基本構成要素となっている[2][8]。.NETのObservableは、LINQ(Language Integrated Query)との親和性が高く、クエリベースでデータストリームを処理することが可能である。また、IObservable<T>インターフェースを通じて、サブスクリプションメカニズムや通知システムが実装されており、データストリームの処理をシンプルに記述できる。特に、非同期APIの設計やリアルタイム処理においてその力を発揮する。

シークエンスと通知メカニズム

[編集]

Observableの中心には、データやイベントのシークエンスがあり、これらは時間の経過に伴って連続的に発生する[1][13][14][31]。Observableは、このシークエンスを監視し、データやイベントが発生する度に購読者(オブザーバーやサブスクライバー)に対して通知を送る。この通知メカニズムは、購読者がObservableに対して購読を行うことで、いわゆるサブスクリプションを通じて実現される。購読者はObservableにサブスクライブすることで、その後発生するデータやイベントのシークエンスに基づいた通知を受け取り、そのデータに対する処理を実行する。

購読者は、受け取ったデータやイベントに応じた処理をリアルタイムで行うことができるだけでなく、サブスクリプションの解除(購読のキャンセル)を任意のタイミングで行うことができる[1][13][14][31]。これにより、必要なデータ処理が完了した段階で購読を終了し、リソースの消費を抑えることができる。特に長時間継続するデータストリームやイベントストリームにおいて、不要になった購読を解除することで効率的なシステム運用が可能となる。

通知は通常、以下の三つの形式で行われる[1][13][14][31]

  1. onNext:データやイベントが発生した際に、その値を購読者に通知する。これが最も頻繁に発生する通知形式であり、Observableが連続的なデータのストリームを送信しているときに各データを購読者に伝達する。購読者はこの通知を受け取ることで、データを逐次処理する。
  2. onError:データシークエンスの途中でエラーが発生した場合、onError通知が送信され、購読者にそのエラー内容が通知される。この通知を受け取った時点で、ストリームの処理は即座に停止し、Observableはそれ以上データを発行しない。onErrorが送信されると、サブスクリプションも終了する。
  3. onCompleted:データやイベントのシークエンスが正常に完了した場合、onCompleted通知が購読者に送られる。これはデータストリームが終了し、これ以上通知が行われないことを意味する。onCompletedは、エラー無しでシークエンスが最後まで処理された場合に送信され、これを以てサブスクリプションは終了する。

このような通知メカニズムにより、購読者はデータストリームの開始から終了までを通して、適切なタイミングでデータを処理したり、エラー発生時の対処を行ったり、ストリームの正常な完了を確認したりすることが可能になる[1][13][14][31]。特にリアクティブプログラミングの文脈において、これらの通知形式はデータフローを制御し、非同期処理の複雑さを簡潔に管理するための重要な要素となっている。

メモリ管理とエラー処理

[編集]

Observableの実装においては、メモリ管理とエラー処理が特に重要な課題となる[1][13][14][31]。メモリ管理に関しては、購読者(オブザーバーやサブスクライバー)が不要になった際に、これを適切に解除することが不可欠であり、適切に解除されることでリソースリークメモリリーク)を防ぐことができる。特に、長時間稼働するシステムや大規模なデータストリームを処理する環境では、サブスクリプションの解除が遅れると、不要となったリソースが解放されず、メモリが無駄に消費され続ける問題が生じる。これを適切に管理しないと、システム全体のパフォーマンスが低下し、最悪の場合はシステムのクラッシュを引き起こす可能性がある。

多くのObservableライブラリでは、メモリ管理を支援するために、サブスクリプションの自動解除やガベージコレクションとの統合が実装されている[1][13][14][31]。これにより、購読が不要になった際に自動的にリソースが解放され、開発者が手動でメモリ管理を行う必要が減少する。例えば、購読者がストリームから離脱した際、ライブラリは自動的にサブスクリプションを解除し、リソースを解放する仕組みを提供している。また、ガベージコレクションと統合することで、不要なオブジェクトが自動的にメモリから削除され、メモリリークを防ぐ。これにより、メモリ管理が効率化され、開発者がメモリの解放に過度に気を配る必要がなくなる。

一方、エラー処理は、データストリーム中に発生する可能性のあるエラーを適切にキャッチし、システムの堅牢性(ロバストネス)を確保するために重要な要素である[1][13][14][31]。特に、非同期のデータストリームでは、エラーがどのタイミングで発生するかを事前に予測することは難しいため、システム全体がエラーによってクラッシュしないようにするための適切なエラーハンドリングが求められる。Observableの実装では、エラー処理のためのオペレーターが豊富に用意されており、これらを利用することでエラー時の挙動を制御することができる。

例えば、catchオペレーターは、データストリーム中にエラーが発生した際、そのエラーをキャッチし、代替のデータストリームに置き換える処理を提供する[1][13][14][31]。これにより、エラーが発生してもストリームの流れを止めることなく処理を継続できる。また、retryオペレーターは、エラーが発生した際に自動的にストリームの再試行を行う機能を提供する。これにより、エラーが一時的なものであれば再試行によって処理を成功させることが可能になる。

このようなエラーハンドリングのオペレーターを組み合わせて使用することで、システム全体の堅牢性を向上させることができ、予期せぬエラーが発生した場合でも、システムが適切に動作を続けられるようになる[1][13][14][31]。エラーハンドリングの柔軟性は、Observableを使用したリアクティブプログラミングにおける重要な要素であり、システムの安定性可用性を維持するための鍵となる。

応用例

[編集]

Webアプリケーションにおける利用

[編集]

Observableは、Webアプリケーションの開発において強力なツールとして活用されている[1][9]。特に、ユーザーインターフェースのイベントハンドリングやリアルタイムデータの表示において重要な役割を果たす。例えば、ユーザーがボタンをクリックしたり、フォームに入力したりする操作に応じて、非同期的にデータを取得し、ページの一部を更新する場合にObservableが利用される。さらに、WebSocketサーバーからのストリーミングデータを処理し、リアルタイムでのデータ更新や通知を可能にするため、動的で応答性の高いWebアプリケーションの実現に貢献している。

データストリーミングとリアクティブプログラミング

[編集]

データストリーミングは、連続的に生成されるデータをリアルタイムで処理する技術であり、Observableはこの文脈で広く利用されている[1][2]。例えば、センサーデータのリアルタイムモニタリング[39]金融市場のリアルタイム価格情報の取得[40]ソーシャルメディアフィードのライブ更新[41]などにObservableが活用される。リアクティブプログラミングの概念に基づき、データストリームに対してリアクティブ(敏感)に反応し、必要な処理を直ちに実行することができる。このアプローチにより、システムの応答性とスケーラビリティが大幅に向上し、継続的なデータフローを効率的に管理することが可能となる。

マイクロサービスと非同期通信

[編集]

マイクロサービスアーキテクチャにおいて、非同期通信は重要な設計要素であり、Observableはこれを実現するための手段として利用される[20][42]。マイクロサービス間の通信では、リクエストとレスポンスの非同期処理が求められることが多く、Observableを使用することで、各サービスが独立して動作しつつも効率的に連携することが可能となる。例えば、サービスAがサービスBにリクエストを送り、その応答を待つことなく他の処理を進めることができる。また、サービス間のイベント駆動型のデータ共有においても、Observableはリアルタイムでのデータ転送と処理を容易にする。このように、Observableを活用することで、マイクロサービスの柔軟性とスケーラビリティが向上する。

ゲーム開発における利用

[編集]

Observableは、ゲーム開発においても重要な役割を果たしている[11][12]ゲーム内のイベント処理やリアルタイムのユーザーインタラクションの管理、非同期的なゲームロジックの実行など、多岐に渡る用途で利用される。例えば、プレイヤーの操作をリアルタイムで反映させる処理や、ネットワーク通信を介してプレイヤー間で同期を取る処理などにObservableが用いられる。さらに、ゲームの状態管理や、複数の非同期タスクの調整においても、Observableは有効である。これにより、複雑なゲームロジックをシンプルに構築し、プレイヤーに対してスムーズでシームレスな体験を提供することができる。

Observableの利点と欠点

[編集]

非同期処理における利点

[編集]

Observableは、非同期処理を簡潔かつ効率的に扱うための強力なツールである[1][13][14][31]。特に、複数の非同期タスクを直列または並列で処理し、その結果を柔軟に制御できる点が大きな利点である。Observableは、イベント駆動型のシステム設計を支援し、リアルタイムで発生するデータストリームに対して反応することができるため、動的なデータ処理を必要とするアプリケーションにおいて非常に有効である。例えば、ユーザーインターフェースの更新やリアルタイムデータの監視といったシナリオでは、Observableを活用することで、常に最新の情報を画面に反映させることが容易になる。このリアルタイム性が、特に動的なWebアプリケーションやリアルタイム分析システムにおいて不可欠な役割を果たしている。

さらに、Observableは多くのオペレーターを提供しており、これによりデータを効率的に変換・フィルタリングすることが可能である[1][13][14][31]。これらのオペレーターを活用することで、複雑なデータフローを直感的かつシンプルに管理でき、非同期処理に伴うコールバック地獄や複雑な状態管理を回避することができる。具体的には、mapオペレーターを使ってデータを変換したり、filterオペレーターを用いて特定の条件に合致するデータのみを処理することができるため、処理の流れをシンプルに保つことができる。また、こうしたオペレーターによって、データの流れを宣言的に記述できるため、コードの可読性や保守性が大幅に向上する。これにより、開発者は非同期処理の煩雑さに煩わされることなく、効果的かつ効率的なコードを記述することが可能となる。

シンプルさと複雑さのトレードオフ

[編集]

Observableは、その柔軟性と強力な機能を提供する一方で、学習曲線の急峻さや実装の複雑さという課題も伴う[1][13][14][31]。Observableは非同期処理を簡潔に扱える一方で、その概念やオペレーターの使い方を十分に理解するには、一定量の学習が必要となる。特に、リアクティブプログラミングに不慣れな初学者にとっては、Observableの仕組みやオペレーターの多様な使い方を習得することが難しく、敷居が高いと感じられることがある。さらに、オペレーターの使用方法を正しく理解していないと、誤ったデータ処理の流れを作成してしまう可能性もあり、Observableの効率性を最大限に引き出すには十分な知識が必要となる。

また、複数のオペレーターを組み合わせた複雑なデータフローの設計では、コードが冗長になり、可読性が低下することも考えられる[1][13][14][31]。特に、複雑なデータストリームを処理する際に、多数のオペレーターをチェーンさせると、コードが一見して理解しにくいものとなるリスクがある。このため、Observableを利用する際には、シンプルさと複雑さのバランスを取ることが重要であり、必要以上に複雑な処理を避け、明確で読みやすいコードを心掛けることが求められる。また、Observableのオペレーションは非同期で行われるため、同期処理に比べてデバッグが難しいという課題もある。タイミングやスレッドの問題が絡むと、デバッグが煩雑化し、バグの発見が難しくなることもあるため、開発者はデバッグツールの使用や適切なロギングを取り入れるなど、工夫が必要となる。

スケーラビリティとパフォーマンスの観点から

[編集]

Observableは、スケーラビリティとパフォーマンスの観点からも優れた選択肢である[1][13][14][31]。非同期処理において、Observableは複数のタスクを効率的に管理し、限られたリソースを最大限に活用することで、リソースの無駄を最小限に抑えることができる。特に、リアクティブプログラミングのアプローチを採用することで、システム全体のスループットを向上させながら、迅速なレスポンス(応答)が可能となる。リアクティブプログラミングは、システムがデータの変化に即座に反応するという設計を実現するため、アプリケーションが多数のユーザーやイベントにリアルタイムで対応する際に非常に効果的である。さらに、Observableのストリーム処理は、連続的に発生するデータの流れをリアルタイムで処理するため、スケーラビリティの高いアプリケーション開発に理想的な選択肢となっている。

一方で、Observableを使用する際には、パフォーマンスへの慎重な配慮が必要である[1][13][14][31]。特に、大量のデータをリアルタイムで処理するアプリケーションでは、適切なオペレーターの選択やサブスクリプションの管理が行われない場合、メモリ使用量が過剰に増加したり、処理の遅延が発生したりなどする可能性がある。例えば、長時間に渡ってデータをストリーム処理する場合、不要になったサブスクリプションが適切に解除されないとメモリリークが発生し、パフォーマンスに悪影響を及ぼすことがある。また、複雑なデータフローを処理する際には、各オペレーターのパフォーマンス特性を理解し、効率的なデータ処理ができるように設計することが重要である。このため、Observableを利用する際には、パフォーマンスチューニングや適切なリソース管理が不可欠であり、スケーラブルなアプリケーションの運用には、これらの最適化が求められる。

関連技術

[編集]

プロミスとの比較

[編集]

Observableとプロミスは、どちらも非同期処理を扱うための技術であるが、その特性と用途は異なる[注釈 2][1][2]。プロミスは、単一の非同期処理の結果を表現し、その結果が解決(fulfilled)されるか、失敗(rejected)するまでの状態を管理する。一度解決されたプロミスは、以降変更されることがなく、複数のイベントや連続したデータストリームを扱うには適していない。一方、Observableは、継続的なデータストリームや複数の非同期イベントを処理するために設計されており、データが発生する度に購読者(オブザーバーやサブスクライバー)に通知を送ることができる。また、Observableはオペレーターを使用して、データストリームの変換やフィルタリングを柔軟に行えるため、より複雑な非同期処理を簡潔に管理できる。これにより、プロミスよりも広範な用途に適しているが、その分、学習コストや実装の複雑さが増すという側面もある。

フューチャーとの比較

[編集]

フューチャーは、プロミスに似た非同期処理の結果をラップするオブジェクトであり、主に並行処理や並列処理の文脈で使用される[注釈 2][37][45]。フューチャーは、非同期タスクの結果を表現し、その結果が利用可能になると、指定された処理を実行する。プロミスと同様に、一度結果が得られると、その後の状態は固定されるため、Observableのように継続的なデータストリームの処理には適していない。フューチャーは、複数の非同期タスクを組み合わせて、一連の処理を構築するためのツールとして有用であるが、リアルタイムデータやイベント駆動型の処理には対応しづらい。一方、Observableは、複数のイベントやデータの変化を連続的に扱うことができるため、リアクティブプログラミングの文脈でより効果的に機能する。

イベントループとリアクター

[編集]

イベントループリアクターは、非同期処理を実現するための重要な基盤技術であり、Observableと密接に関連している[2][47]。イベントループは、非同期タスクをキューに追加し、それらを順次処理する仕組みであり、JavaScriptのランタイム環境などで広く使用されている。リアクターは、イベントループをベースにして、イベント駆動型の処理を効率的に管理するデザインパターンであり、非同期I/O処理を効率化するために使用される。Observableは、これらの技術と連携することで、イベント駆動型の非同期処理を簡潔に表現し、複雑なデータフローを管理できる。例えば、JavaScriptではイベントループを利用して、非同期イベントを処理し、RxJSを通じてObservableの機能を実現する。また、リアクターは、非同期処理のスケジューリングと効率的なリソース管理を提供し、Observableを使ったリアクティブプログラミングの実装に役立つ。このように、Observableはイベントループとリアクターの基盤技術を活用し、非同期処理を強化するツールとして機能する。

歴史と発展

[編集]

Observableの進化と現在の動向

[編集]

Observableの概念は、オブザーバーパターンを基盤として進化してきた[1][2]。このパターンは、元々オブジェクト指向デザインにおいて、オブジェクト間の疎結合を保ちながら状態の変化を通知するために使用されていた。リアクティブ拡張(: Reactive Extensions、Rx)の登場により、Observableは非同期データストリームを管理するための中心的な役割を担うようになった。特に、MicrosoftがRxを開発し、.NET Frameworkの一部として導入したことで、Observableの利用が広がった。その後、Python、Java、JavaScriptなど、他の言語にもRxが移植され、リアクティブプログラミングの基本ツールとして定着している。

リアクティブプログラミングの需要が高まる中で、Observableはさらに重要な技術となっている[1][20]Web開発[9]モバイルアプリ開発[48]、サーバーサイドの非同期処理[1]など、様々な領域で利用され、リアルタイムでのデータ処理が求められるシステムにおいてその価値を発揮している。さらに、クラウドベースのマイクロサービスアーキテクチャ[20]や、IoTデバイス間のデータ通信[39]においても、Observableはスケーラブルで応答性の高いシステムを構築するための鍵となっている。

リアクティブプログラミングの潮流

[編集]

リアクティブプログラミングは、システムが動的に変化するデータやイベントに対して即座に反応するプログラミングパラダイムであり、Observableはその中心的な役割を果たしている[1][13]。リアクティブプログラミングの考え方は、リアクティブシステムの設計原則に基づいており、これには応答性、回復性、弾力性、メッセージ駆動性が含まれる。これらの原則は、モダンな分散システムや大規模なアプリケーションにおいて重要視されている。

リアクティブプログラミングの潮流は、データ量が増大し、リアルタイムでの処理が求められる現代のアプリケーション開発においてさらに加速している[49][31]。特に、ストリーミングデータの処理、複雑なイベント処理、ユーザーインターフェースの即時更新など、応答性が求められるシステムにおいては、Observableのようなツールが不可欠である。リアクティブプログラミングは、これまでの命令型プログラミングとは異なり、データの流れやイベントに基づいてシステムが自然に反応することを目指しており、その結果として開発者はより直感的で柔軟なアプリケーションを構築できるようになっている。

Observableの問題と課題

[編集]

デバッグの難しさ

[編集]

Observableは非常に強力なツールである一方で、そのデバッグは難しいとされている[1][7]。Observableを使った非同期処理は、連続するデータストリームやイベントの処理が複雑なフローを形成することが多く、エラーの発生源や処理の流れを追跡するのが困難になる場合がある。さらに、Observableの非同期性や、オペレーターによる処理の遅延や結合などが影響し、問題の特定が難しくなることも多い。このため、従来の同期的なデバッグ手法では不十分であり、特別なデバッグツールや手法を必要とすることがある。また、Observableのエラーハンドリングは強力だが、エラーの発生場所やその影響を完全に把握するためには深い理解が必要である。

保守性と学習曲線

[編集]

Observableを利用したコードは、強力な機能を提供する反面、その保守性に課題を抱えることがある[1][7]。Observableのオペレーターやデータフローが複雑化すると、コードの可読性が低下し、変更や拡張が難しくなる場合がある。また、Observable自体が高度な抽象化を伴うため、新しい開発者や経験の浅い開発者にとっては学習曲線が急峻であると感じられることが多い。リアクティブプログラミングの概念や、Observableの内部動作を深く理解するためには、多くの時間と経験が必要である。このため、チームでのコーディング標準やベストプラクティスを確立し、コードの保守を容易にする工夫が求められる。

マルチスレッドとコンカレンシーとの統合

[編集]

Observableは、非同期処理のパターンをシンプルに表現できるが、マルチスレッドコンカレンシーとの統合においては注意が必要である[1][13][14][31]。特に、Observableが複数のスレッドで動作する場合、スレッド間でデータの共有や競合状態が発生する可能性がある。これらの競合状態を適切に管理しないと、予期せぬ動作やデータの不整合、さらにはパフォーマンスの低下を引き起こすリスクがある。例えば、複数のスレッドが同じデータストリームにアクセスし、同時にデータの読み書きを行う状況では、スレッド間での同期が適切に行われていないと、競合状態が発生し、結果としてエラーが発生する可能性が高くなる。

また、Observable自体はスレッドセーフではないため、複数のスレッドで同じObservableを利用する際には、外部の同期機構を使用する必要がある[1][13][14][31]。例えば、lockmutexのような同期ツールを用いて、スレッド間のアクセスを調整することで、データの整合性を確保し、予期しない動作を防ぐことができる。しかし、これらの同期機構を正しく適用しない場合、デッドロックやスレッドの停止といった問題が発生するリスクもあるため、適用には十分な注意が求められる。

さらに、マルチスレッド環境でのObservableの動作を正しく理解し、適切に設計することは難しく、これはコンカレンシーとの統合におけるObservableの大きな課題の一つである[1][13][14][31]。特に、スレッドの管理や非同期タスクの調整を誤ると、パフォーマンスの低下だけでなく、システム全体の不安定性にも繋がりかねない。このため、マルチスレッド環境でObservableを使用する際には、スレッド管理や同期処理に関する深い知識が必要となる。特に、複雑な非同期処理を伴うシステムにおいては、こうした知識が不可欠であり、システムの安定性を維持しつつ効率的に動作させるためには、設計段階での慎重な検討が求められる。

脚注

[編集]

注釈

[編集]
  1. ^ 「GoF」は「Gang of Four(ギャング・オブ・フォー)」の略。「Gang」という言葉は、ここではGoF本の著者四人を指して「グループ」や「集団」という意味で使われている。「Gang of Four」は、彼らが共同で重要な功績を残した四人のチームであることを示すための親しみを込めた表現である[16][17][25][26]英語圏では「gang」という言葉が、必ずしも否定的な意味ではなく、特定の目的や目標を共有する集団を表す場合にカジュアルに使われることがある[27][28][29][30]。したがって、彼らの影響力を強調するために「Gang」が用いられている。
  2. ^ a b プロミスとフューチャーはデザインパターンではない[43][44][45][46]。以下は書籍『You Don't Know JS: ES6 & Beyond』で述べられている、デザインパターンではないという説明の引用である。
    "Promises and Futures are not design patterns, but rather fundamental constructs that aid in managing asynchronous code in JavaScript." — Chapter 4: Async Flow Control

出典

[編集]
  1. ^ a b c d e f g h i j k l m n o p q r s t u v w x y z aa ab ac ad ae af ag ah ai aj ak al am an ao ap aq ar as at au av aw ax ay az ba bb bc bd be bf bg bh bi Nurkiewicz, Tomasz; Christensen, Ben (2016-10-06) (英語). Reactive Programming with RxJava: Creating Asynchronous, Event-Based Applications. "O'Reilly Media, Inc.". ISBN 978-1-4919-3160-8. https://www.google.co.jp/books/edition/Reactive_Programming_with_RxJava/gYY1DQAAQBAJ?hl=ja&gbpv=1&dq=Reactive+Programming+with+RxJava&printsec=frontcover 
  2. ^ a b c d e f g h i j Liberty, Jesse; Betts, Paul (2012-02-01) (英語). Programming Reactive Extensions and LINQ. Apress. ISBN 978-1-4302-3748-8. https://www.google.co.jp/books/edition/Programming_Reactive_Extensions_and_LINQ/EQVkDCMB0rMC?hl=ja&gbpv=1&dq=Programming+Reactive+Extensions+and+LINQ&printsec=frontcover 
  3. ^ a b Brattli, Dag (2016-11-30) (英語). Python Reactive Programming. Packt Publishing, Limited. ISBN 978-1-78646-344-9. https://www.google.co.jp/books/edition/Python_Reactive_Programming/KLu8jwEACAAJ?hl=ja 
  4. ^ a b Slatkin, Brett (2015) (英語). Effective Python: 59 Specific Ways to Write Better Python. Addison-Wesley. ISBN 978-0-13-403441-6. https://www.google.co.jp/books/edition/Effective_Python/dmmCrgEACAAJ?hl=ja 
  5. ^ a b Tuominen, Timo (2019-04-17) (英語). RxJava for Android Developers. Simon and Schuster. ISBN 978-1-63835-125-2. https://www.google.com/books/edition/RxJava_for_Android_Developers/ajszEAAAQBAJ?kptab=editions&sa=X&ved=2ahUKEwiUr4_cn-KHAxWkgK8BHe2cASMQmBZ6BAgMEAo 
  6. ^ a b c d e f Daniels, Paul; Atencio, Luis (2017-07-20) (英語). RxJS in Action. Simon and Schuster. ISBN 978-1-63835-170-2. https://www.google.co.jp/books/edition/RxJS_in_Action/mjszEAAAQBAJ?hl=ja&gbpv=1&dq=RxJS+in+Action&printsec=frontcover 
  7. ^ a b c d e f g h i j k l m n Oliveira, Erich de Souza (2017-05-26) (英語). Mastering Reactive JavaScript. Packt Publishing Ltd. ISBN 978-1-78646-346-3. https://www.google.co.jp/books/edition/Mastering_Reactive_JavaScript/nnc5DwAAQBAJ?hl=ja&gbpv=1&dq=Mastering+Reactive+JavaScript:+Building+Asynchronous+and+High-performing+Applications+with+React+and+RxJS&printsec=frontcover 
  8. ^ a b Terrell, Riccardo (2018) (英語). Concurrency in .NET. Manning Publications. https://www.google.co.jp/books/edition/Concurrency_in_NET/EPUOzgEACAAJ?hl=ja 
  9. ^ a b c Bernhardt, Manuel (2016-06-27) (英語). Reactive Web Applications: Covers Play, Akka, and Reactive Streams. Simon and Schuster. ISBN 978-1-63835-339-3. https://www.google.co.jp/books/edition/Reactive_Web_Applications/hTkzEAAAQBAJ?hl=ja&gbpv=1&dq=Reactive+Web+Applications&printsec=frontcover 
  10. ^ Richardson, Chris (2018-10-27) (英語). Microservices Patterns: With examples in Java. Simon and Schuster. ISBN 978-1-63835-632-5. https://www.google.co.jp/books/edition/Microservices_Patterns/QTgzEAAAQBAJ?hl=ja&gbpv=1&dq=Microservices+Patterns:+With+examples+in+Java&printsec=frontcover 
  11. ^ a b Nystrom, Robert (2014-11-03) (英語). Game Programming Patterns. Genever Benning. ISBN 978-0-9905829-1-5. https://www.google.co.jp/books/edition/Game_Programming_Patterns/9fIwBQAAQBAJ?hl=ja&gbpv=1&dq=Game+Programming+Patterns&printsec=frontcover 
  12. ^ a b Spell, Terrill Brett (2015-05-29) (英語). Pro Java 8 Programming. Apress. ISBN 978-1-4842-0641-6. https://www.google.co.jp/books/edition/Pro_Java_8_Programming/Nl4nCgAAQBAJ?hl=ja&gbpv=1&dq=Pro+Java+8+Programming&printsec=frontcover 
  13. ^ a b c d e f g h i j k l m n o p q r s t u v w x y z aa ab ac ad ae af ag ah ai aj ak al am an Allen, Jamie (2017-02-21) (英語). Reactive Design Patterns. Simon and Schuster. ISBN 978-1-63835-405-5. https://www.google.co.jp/books/edition/Reactive_Design_Patterns/xzozEAAAQBAJ?hl=ja&gbpv=1&dq=Reactive+Design+Patterns&printsec=frontcover 
  14. ^ a b c d e f g h i j k l m n o p q r s t u v w x y z aa ab ac ad ae af ag ah ai aj Dokuka, Oleh; Lozynskyi, Igor (2018-10-08) (英語). Hands-On Reactive Programming in Spring 5: Build cloud-ready, reactive systems with Spring 5 and Project Reactor. Packt Publishing Ltd. ISBN 978-1-78728-729-7. https://www.google.co.jp/books/edition/Hands_On_Reactive_Programming_in_Spring/3iZyDwAAQBAJ?hl=ja&gbpv=1&dq=Hands-On+Reactive+Programming+in+Spring+5&printsec=frontcover 
  15. ^ Thomas, David; Hunt, Andrew (2019-07-30) (英語). The Pragmatic Programmer: Your journey to mastery, 20th Anniversary Edition. Addison-Wesley Professional. ISBN 978-0-13-595691-5. https://www.google.co.jp/books/edition/The_Pragmatic_Programmer/LhOlDwAAQBAJ?hl=ja&gbpv=1&dq=The+Pragmatic+Programmer+2019&printsec=frontcover 
  16. ^ a b c Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John (1994-10-31) (英語). Design Patterns: Elements of Reusable Object-Oriented Software. Pearson Education. ISBN 978-0-321-70069-8. https://www.google.co.jp/books/edition/_/6oHuKQe3TjQC?hl=ja&sa=X&ved=2ahUKEwjLo7irnLCIAxXbr1YBHbncNt8Q7_IDegQIAxBn 
  17. ^ a b Freeman, Eric; Robson, Elisabeth; Freeman, Elisabeth; Sierra, Kathy; Bates, Bert (2004-10-25) (英語). Head First Design Patterns. "O'Reilly Media, Inc.". ISBN 978-0-596-00712-6. https://www.google.co.jp/books/edition/Head_First_Design_Patterns/GGpXN9SMELMC?hl=ja&gbpv=1&dq=Head+First+Design+Patterns&printsec=frontcover 
  18. ^ a b Hohpe, Gregor; Woolf, Bobby (2004) (英語). Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions. Addison-Wesley Professional. ISBN 978-0-321-20068-6. https://www.google.co.jp/books/edition/_/bUlsAQAAQBAJ?hl=ja&sa=X&ved=2ahUKEwi725P3nLCIAxXgk1YBHaLVFdwQ7_IDegQIEBAC 
  19. ^ Burns, Brendan (2018-02-20) (英語). Designing Distributed Systems: Patterns and Paradigms for Scalable, Reliable Services. "O'Reilly Media, Inc.". ISBN 978-1-4919-8361-4. https://www.google.co.jp/books/edition/Designing_Distributed_Systems/5hJNDwAAQBAJ?hl=ja&gbpv=0 
  20. ^ a b c d Newman, Sam (2015-02-02) (英語). Building Microservices: Designing Fine-Grained Systems. "O'Reilly Media, Inc.". ISBN 978-1-4919-5033-3. https://www.google.co.jp/books/edition/Building_Microservices/jjl4BgAAQBAJ?hl=ja&gbpv=1&dq=Building+Microservices&printsec=frontcover 
  21. ^ a b c Schildt, Herbert (2018-12-14) (英語). Java: The Complete Reference, Eleventh Edition. McGraw Hill Professional. ISBN 978-1-260-44024-9. https://www.google.co.jp/books/edition/Java_The_Complete_Reference_Eleventh_Edi/-W57DwAAQBAJ?hl=ja&gbpv=1&bsq=Java:+The+Complete+Reference+2019&dq=Java:+The+Complete+Reference+2019&printsec=frontcover 
  22. ^ a b c d Akidau, Tyler; Chernyak, Slava; Lax, Reuven (2018-07-16) (英語). Streaming Systems: The What, Where, When, and How of Large-Scale Data Processing. "O'Reilly Media, Inc.". ISBN 978-1-4919-8382-9. https://www.google.co.jp/books/edition/Streaming_Systems/TAxlDwAAQBAJ?hl=ja&gbpv=0 
  23. ^ Kleppmann, Martin (2017-03-16) (英語). Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems. "O'Reilly Media, Inc.". ISBN 978-1-4919-0311-7. https://www.google.co.jp/books/edition/Designing_Data_Intensive_Applications/zFheDgAAQBAJ?hl=ja&gbpv=1&dq=Designing+Data-Intensive+Applications:+The+Big+Ideas+Behind+Reliable,+Scalable,+and+Maintainable+Systems&printsec=frontcover 
  24. ^ Gamma, Erich (1994) (英語). Design Patterns: Elements of Reusable Object-oriented Software. Addison-Wesley. ISBN 978-81-317-3638-8. https://www.google.co.jp/books/edition/_/vqp2AQAACAAJ?hl=ja&sa=X&ved=2ahUKEwiS172boLCIAxULsVYBHQFTBwEQ7_IDegQIKBAC 
  25. ^ Buschmann, Frank; Meunier, Regine; Rohnert, Hans; Sommerlad, Peter; Stal, Michael (1996-08-16) (英語). Pattern-Oriented Software Architecture, A System of Patterns. Wiley. ISBN 978-0-471-95869-7. https://www.google.co.jp/books/edition/Pattern_Oriented_Software_Architecture_A/sE6s0AEACAAJ?hl=ja 
  26. ^ Larman, Craig (2005) (英語). Applying UML and Patterns: An Introduction to Object-oriented Analysis and Design and Iterative Development. Pearson. ISBN 978-81-7758-979-5. https://www.google.co.jp/books/edition/Applying_UML_and_Patterns/qp1QQDHxuvAC?hl=ja 
  27. ^ David Crystal (1995 [repr. 1996]) (英語). The Cambridge encyclopedia of the English language. Cambridge University Press. https://search.worldcat.org/ja/title/1158700854 2024年9月7日閲覧。 
  28. ^ Ammer, Christine (1997) (英語). The American Heritage Dictionary of Idioms. Houghton Mifflin. ISBN 978-0-395-72774-4. https://www.google.co.jp/books/edition/_/1D_6wAEACAAJ?hl=ja&sa=X&ved=2ahUKEwjvi43z67CIAxXLhlYBHccBMoAQre8FegQIAxAy 
  29. ^ Adams, Michael (2023) (英語). Slang: The People's Poetry. Oxford University Press. ISBN 978-0-19-772241-1. https://www.google.co.jp/books/edition/_/uDNR0AEACAAJ?hl=ja&sa=X&ved=2ahUKEwjW6rec7LCIAxXZs1YBHfWLCOAQ7_IDegQIFBAE 
  30. ^ John Ayto, J. A. Simpson (2009) (英語). Stone the crows: Oxford dictionary of modern slang. Oxford University Press. https://search.worldcat.org/ja/title/507971750 2024年9月7日閲覧。 
  31. ^ a b c d e f g h i j k l m n o p q r s t u v w x y z aa ab ac Escoffier, Clement (2017) (英語). Building Reactive Microservices in Java: Asynchronous and Event-based Application Design. O'Reilly Media. https://www.google.co.jp/books/edition/Building_Reactive_Microservices_in_Java/ts9swAEACAAJ?hl=ja 
  32. ^ a b Bloch, Joshua『Effective Java』丸善出版、2018年10月。ISBN 978-4-621-30325-2https://www.google.co.jp/books/edition/Effective_Java/5jm6vQEACAAJ?hl=ja 
  33. ^ Price, Mark J. (2019-10-31) (英語). C# 8.0 and .NET Core 3.0: Modern Cross-Platform Development: Build Applications with C#, .NET Core, Entity Framework Core, ASP.NET Core, and ML.NET Using Visual Studio Code. Packt Publishing Ltd. ISBN 978-1-78847-157-2. https://www.google.co.jp/books/edition/C_8_0_and_NET_Core_3_0_Modern_Cross_Plat/Qzm8DwAAQBAJ?hl=ja&gbpv=0 
  34. ^ Troelsen, Andrew; Japikse, Philip (2017-11-21) (英語). Pro C# 7: With .NET and .NET Core. Apress. ISBN 978-1-4842-3018-3. https://www.google.co.jp/books/edition/Pro_C_7/Jus_DwAAQBAJ?hl=ja&gbpv=1&dq=Pro+C#+7:+With+.NET+and+.NET+Core&printsec=frontcover 
  35. ^ Goldshtein, Sasha; Zurbalev, Dima; Group, SELA; Flatow, Ido (2012-10-22) (英語). Pro .NET Performance: Optimize Your C# Applications. Apress. ISBN 978-1-4302-4459-2. https://www.google.co.jp/books/edition/Pro_NET_Performance/D3J58cs-i44C?hl=ja&gbpv=1&dq=Pro+.NET+Performance:+Optimize+Your+C#+Applications&printsec=frontcover 
  36. ^ Troelsen, Andrew (2012-10-07) (英語). Pro C# 5.0 and the .NET 4.5 Framework. Apress. ISBN 978-1-4302-4234-5. https://www.google.co.jp/books/edition/Pro_C_5_0_and_the_NET_4_5_Framework/kfZYU5ZGiiMC?hl=ja&gbpv=1&dq=Pro+C#+5.0+and+the+.NET+4.5+Framework&printsec=frontcover 
  37. ^ a b Subramaniam, Venkat (2011-08-26) (英語). Programming Concurrency on the JVM: Mastering Synchronization, STM, and Actors. Pragmatic Bookshelf. ISBN 978-1-68050-430-9. https://www.google.co.jp/books/edition/Programming_Concurrency_on_the_JVM/PA9QDwAAQBAJ?hl=ja&gbpv=1&dq=Programming+Concurrency+on+the+JVM&printsec=frontcover 
  38. ^ Psaltis, Andrew (2017-05-31) (英語). Streaming Data: Understanding the real-time pipeline. Simon and Schuster. ISBN 978-1-63835-724-7. https://www.google.co.jp/books/edition/Streaming_Data/6TczEAAAQBAJ?hl=ja&gbpv=0 
  39. ^ a b Hillar, Gaston C. (2016) (英語). Internet of Things with Python. Packt Publishing. ISBN 978-1-78588-138-1. https://www.google.co.jp/books/edition/Internet_of_Things_with_Python/cjkLkAEACAAJ?hl=ja 
  40. ^ Johnson, Barry (2010) (英語). Algorithmic Trading & DMA: An Introduction to Direct Access Trading Strategies. 4Myeloma Press. ISBN 978-0-9563992-0-5. https://www.google.co.jp/books/edition/Algorithmic_Trading_DMA/xgRcYgEACAAJ?hl=ja 
  41. ^ Russell, Matthew A. (2013-10-04) (英語). Mining the Social Web: Data Mining Facebook, Twitter, LinkedIn, Google+, GitHub, and More. "O'Reilly Media, Inc.". ISBN 978-1-4493-6822-7. https://www.google.co.jp/books/edition/Mining_the_Social_Web/_VkrAQAAQBAJ?hl=ja&gbpv=1&dq=Mining+the+Social+Web&printsec=frontcover 
  42. ^ Bonér, Jonas (英語). Reactive Microservices Architecture: Design Principles for Distributed Systems. O'Reilly Media. ISBN 978-1-4919-5779-0. https://www.google.co.jp/books/edition/Reactive_Microservices_Architecture/7N5IuwEACAAJ?hl=ja 
  43. ^ Crockford, Douglas (2008-05-08) (英語). JavaScript: The Good Parts: The Good Parts. "O'Reilly Media, Inc.". ISBN 978-0-596-55487-3. https://www.google.co.jp/books/edition/JavaScript_The_Good_Parts/PXa2bby0oQ0C?hl=ja&gbpv=1&printsec=frontcover 
  44. ^ Fowler, Matthew (2022-03-15) (英語). Python Concurrency with asyncio. Simon and Schuster. ISBN 978-1-63835-708-7. https://www.google.co.jp/books/edition/Python_Concurrency_with_asyncio/M9xdEAAAQBAJ?hl=ja&gbpv=1&dq=Python+Concurrency+with+asyncio&printsec=frontcover 
  45. ^ a b Goetz, Brian (2006) (英語). Java Concurrency in Practice. Addison-Wesley. ISBN 978-0-321-34960-6. https://www.google.co.jp/books/edition/Java_Concurrency_in_Practice/6LpQAAAAMAAJ?hl=ja&gbpv=1&bsq=Java+Concurrency+in+Practice&dq=Java+Concurrency+in+Practice&printsec=frontcover 
  46. ^ Albahari, Joseph; Albahari, Ben (2015) (英語). C# 6.0 in a Nutshell. O'Reilly. https://www.google.co.jp/books/edition/C_6_0_in_a_Nutshell/IqS8zwEACAAJ?hl=ja 
  47. ^ Casciaro, Mario (2014) (英語). Node.js Design Patterns: Get the Best Out of Node.js by Mastering a Series of Patterns and Techniques to Create Modular, Scalable, and Efficient Applications. Packt Publishing. ISBN 978-1-78328-731-4. https://www.google.com/books/edition/_/GRICrgEACAAJ?sa=X&ved=2ahUKEwiR_67oseKHAxUk3zQHHQzVCdkQ7_IDegQIGxAD 
  48. ^ Tsvetinov, Nickolay (2015-06-24) (英語). Learning Reactive Programming with Java 8. Packt Publishing Ltd. ISBN 978-1-78528-250-8. https://www.google.co.jp/books/edition/Learning_Reactive_Programming_with_Java/5GT9CQAAQBAJ?hl=ja&gbpv=1&dq=Learning+Reactive+Programming+with+Java+8&printsec=frontcover 
  49. ^ Escoffier, Clement; Finnigan, Ken (2021-11-10) (英語). Reactive Systems in Java. "O'Reilly Media, Inc.". ISBN 978-1-4920-9169-1. https://www.google.co.jp/books/edition/Reactive_Systems_in_Java/yZFNEAAAQBAJ?hl=ja&gbpv=0 

関連項目

[編集]