2020年10月31日土曜日

SimpleModel/関数

前回は以下に示すクラウド・アプリケーションの各種特性に対してアプリケーション・アーキテクチャへの影響を整理した後、SimpleModel 2020(SM2020)のメタモデル設計の方針検討を行いました。

  • 並列
  • 分散
  • スケーラビリティ
  • アベイラビリティ
  • リアルタイム
  • UI

続けてラウド・アプリケーションを構成する以下の各種要素技術に対して、SM2020のメタモデル設計の方針検討を行います。

  • 関数
  • CQRS
  • Event Sourcing
  • Eventually consistency
  • マイクロサービス
  • BigData
  • AI
  • IoT
  • DevOps

今回は、関数について検討します。

関数

プログラミング言語における「関数」は、C言語の手続き的な関数から、Haskellのような純粋関数型言語の関数まで非常に広い幅があります。

ここでは、Haskellのような純粋関数型言語やScalaのようなオブジェクト指向と関数型のハイブリット言語における紳士協定的な関数まで、数理モデルに基づく特性を意図した「関数」を関数と呼ぶことにします。

プログラミングにおける関数の長所としては以下のものを挙げることができます。

  • バグが出にくい
  • 生産性が高い
  • 並列・分散処理の記述に適している

ボクの体感でも静的型付け言語の場合、オブジェクト指向プログラミングより関数型プログラミングの方が圧倒的に生産性が高く、バグも出にくいと思います。

ただし、関数型言語には以下の短所があります。

  • 実行時性能がやや不利
  • 状態を持つプログラムの記述が困難
  • 外界との入出力の記述が大変

実行時性能がやや不利な点は近年のハードウェアの進化により、よほどのクリティカルな箇所でない限り実用上の問題にはならないでしょう。

しかし、「状態を持つプログラムの記述が困難」と「外界との入出力の記述が大変」についてはかなり大きな問題です。この問題はモナドの実用化により大きく緩和されましたが、それでもオブジェクト指向言語に比べると大きな制約であるのは確かです。

得意とするプログラミングの分野という観点からは以下のことが言えると思います。

  • 関数型はアルゴリズムの記述に向いている
  • オブジェクト指向型は外部世界の制御に向いている

また関数型は並列・分散処理に向いているという特性も重要です。

関数型は数理モデルに近い形でアルゴリズムを記述できるので、適切な並列・分散フレームワークを使用することで並列・分散処理そのものはフレームワーク内で自動的に行うことが可能になることを期待できます。一方、オブジェクト指向の場合は並列・分散処理を意識したプログラミングが必要になりがちです。

上記の点から、アプリケーションはできる限り純粋関数型で記述して、外部世界との接続する部分や状態、永続データを扱う部分をオブジェクト指向で記述するというのが、現代的なプログラミングスタイルとなります。

プログラミングの世界がこのような状況になっている以上、プログラミングよりも数理モデル寄りであるモデリングでは、オブジェクト指向と関数型のハイブリッドなアプローチが有効であることが予想されます。

このハイブリッドなアプローチについてSM2020で検討を進めていく予定です。

モデリングの検討

SM2020での関数に対するアプローチは、今の所以下の3つを考えています。

  • ルール
  • データーフロー
  • リアクティブストリーム
ルール

UMLでは直接関数を取り扱うことはできませんが、シングルトン・オブジェクトのオペレーションにステレオタイプをつけるなどの独自拡張で対応可能です。

ただ、モデリングの中で関数が単独で登場することは稀で、一連の関数群として定義することが多いでしょう。

SMでは複数の関数群をルールとして束ねて管理します。ルールは分類子にスレレオタイプruleをつけて表現します。stereotypeSM2020でもこの方式を踏襲します。

ルールは以下のような形で類型化が可能です。

  • 表構造
  • 木構造
  • プログラム
  • AI

たとえば、市町村別配送料といったルールは簡単な表構造で表現可能です。このような場合、モデル内で表データを定義して、ここからプログラムの自動生成を行うなどの手段が考えられます。

データフロー

データフローはユースケース登場後のOOADではあまり使われませんが、ビジネス・アプリケーションのモデリングには有力な技法です。

複数のデータストアに対して入出力を行うビジネス・ロジックの多くは、データフローを使ってモデル化することができます。

また、クラウド・アプリケーションでの重要な応用分野であるBigData, AI, IoTは多種多様なデータソースからのデータを収集し、このデータを複合的に分析・計算することで新しいデータを出力することになるので、データフローモデルを使ってモデリングすることの価値が高いと思われます。

数理モデルとも近い位置にあるモデルなので、適切な実行基盤を得ることができれば、プログラムの自動生成の対象にすることができるのではないかと期待しています。この実行基盤として候補となるのが次項のリアクティブストリームです。

データフローについては、メタモデル内の位置づけやドメイン・モデルなどとの連携について検討を進める予定です。

リアクティブストリーム

イベント駆動のロジックを考える場合、伝統的なオブジェクト指向のアプローチではいわゆるcall back hellとなりがちです。独立して存在するコールバックの集まりが有機的な連携を行い一つのアプリケーションロジックとして動作することになるわけですが、アプリケーションが大きくなってくると、アプリケーションロジックの見通しが悪くなり、仕様追加や変更などを行うことのコストが増大してきます。

この問題を解決する技術がリアクティブストリームです。

リアクティブストリームには以下の長所もあります。

リアクティブストリームは通しのよい関数型プログラミングで、イベント駆動アプリケーションの一連の処理をわかりやすい形で記述することができます。

また、Akka Streamsのような適切な実行基盤を使えばアプリケーションレベルで意識することなく並列・分散処理を行うことができます。

これらの性質を兼ね備えている要素技術がリアクティブストリームです。並列・分散が日常化するクラウド・アプリケーションでは重要な技術になってくると考えています。

このリアクティブ・ストリームで実現するアプリケーションロジックをモデリングの中でどのように扱っていくのかという点はSM2020の中で検討していく予定です。前回説明したとおり、以下のようなモデル図を使ったモデリングが有力と考えています。

  • データフロー図
  • メッセージ図

データストアとの関係を重視したい場合はデータフロー図、パイプライン処理の側面を重視したい場合はメッセージ図という使い分けを想定しています。

まとめ

今回は9つ挙げた要素技術の中で関数を取り上げました。

次回はCQRS、Event Sourcing、Eventually Consistencyについて検討を行う予定です。