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