CatyScriptとファシリティとエンティティ
Catyでは、コマンド/アクション(アクションはコマンドの特殊なもの)は薄緑の楕円で描くことにしている。単なる習慣だけど、習慣を守るとイチイチどうしようかと考えなくて済む。
CatyScriptは徹底的に図式的・絵的(pictorial/graphical/diagrammatic)な設計になっている。テキストで書くコマンドシェル言語だが、有向グラフによる可視化と対応するようになっている。スクリプトの基本要素であるコマンドノードは(今の習慣だと)薄緑の楕円なわけだ。
複数のコマンドノードのあいだを結ぶ矢印(ワイヤー、パイプ、ケーブル)には、まず、データフロー辺がある。CatyScriptでは、データフローと制御フローの区別がない。別な言い方をすると、制御は常にデータと共に流れるのだ。Catyでvoidデータが重要なのは、voidは情報は運ばないが制御を運ぶからだ。つまり、voidデータの受け渡しが、(実質的データ受け渡しを伴わない)制御の受け渡しとなる。
CatyScript/Catyスキーマの図示(可視化)では、ノードとなるコマンド、ワイヤー(のラベル)となる型以外に、次の要素が存在する。
- クライアント状態(state)
- ファシリティ(facility)
これらは、ロバストネス図では:
- バウンダリーオブジェクト
- エンティティオブジェクト
に対応する。もちろん、コマンドはコントロールオブジェクトに対応する。
最近になって、CatyScript/Catyスキーマでも、ファシリティの同義語(微妙に違うがほぼ同じ)として entity という言葉を使うことにした。ファシリティ/エンティティの図示の例は次。
ファイルシステム(Catyではmafsと呼ぶ)に対するファイル書き込みと同時に、KVSに管理用メタデータも書くとする。Data.putアクション(Webから呼び出せるコマンドがアクション)が、ファイルシステムとKVSの両方に書き込みを行う。Data.getアクションは、ファイルシステムからの読み出し。Data.indexアクションが、管理メタデータ一覧(インデックス)をKVSから読む。そういう状況を図示している。
コマンド/アクションとファシリティ/エンティティを結ぶ辺(矢印)は3種類。
- reads : データを読み出す。
- updates : データを書き込んで更新する。
- uses : 読み書きの両方を行う。
[追記]絵を描いたスクリプトを以下に貼る。[/追記]
// -*- coding: utf-8 -*- /* ロバストネス図のバックエンド側のサンプル */ module g; command action-node [string name] :: void -> gv:Node { gv:node --fontsize=14.0 --shape=ellipse --style=filled --color=black --fillcolor=darkseagreen2 %1 }; command entity-node [string name] :: void -> gv:Node { gv:node --fontsize=14.0 --shape=Mcircle --style=filled --color=black --fillcolor=darkorange3 %1 }; /* エッジの指定順序は、常に アクション エンティティ の順 */ command reads-edge [string act, string ent] :: void -> gv:Edge { gv:edge --dir=back --label=reads %1 %2 }; command updates-edge [string act, string ent] :: void -> gv:Edge { gv:edge --label=updates %1 %2 }; command uses-edge [string act, string ent] :: void -> gv:Edge { gv:edge --dir=both --label=uses %1 %2 }; command sample :: void -> gv:Digraph { [ action-node act1, action-node act2, action-node act3, entity-node ent1, entity-node ent2, uses-edge act1 ent1, reads-edge act2 ent1, updates-edge act2 ent2, reads-edge act3 ent2, ] | gv:graph sample }; command sample2 :: void -> gv:Digraph { [ action-node Data.get, action-node Data.put, action-node Data.index, entity-node "mafs\npub", entity-node "kvs\nindex", reads-edge Data.get "mafs\npub", updates-edge Data.put "mafs\npub", updates-edge Data.put "kvs\nindex", reads-edge Data.index "kvs\nindex", ] | gv:graph sample2 }; // End of Module