- グラフは、明確で順序付けられた視覚的構造を持つ必要があります(グラフの頂点とリンクの手動の順序付けは最小限に抑える必要があります)
- グラフファイルはプロジェクトに、したがってバージョン管理システムに含める必要があります。
- グラフの上部には、状態が実装されているファイルへのクリック可能なリンクが必要です。
- グラフの頂点にスタイルを設定する機能を実装する必要があります。
したがって、WPF / MVVMプロジェクトのコンテキストでのステートマシンパターンの実装について十分な資料がある場合、2番目のタスク(遷移グラフジェネレーターの実装)に対する明確な解決策はありませんでした。 しかし、このトピックに関する資料を分析するときに、この記事に出くわしました。 そのため、この記事では、作成者はVisual Studioツール、つまりDGMLファイル(Direct Graph Markup Language)のビジュアルエディターを使用して状態グラフを手動で作成し、受け取ったグラフに基づいて、プログラムで状態マシン遷移テーブルを作成します。
DGMLファイル(指向グラフファイル)にはXML表現があり、その構造はMSDNで詳しく説明されています。 そのため、XML表現をプログラムで編集して、グラフの視覚的表現を変更できます。 したがって、グラフの視覚化ツールが選択され、既存の遷移テーブルに基づいてDGMLファイルのXML表現を形成するジェネレーターを実装します。
そのため、プロジェクトソリューションにDGMLファイルを追加し、テストメソッドでグラフジェネレーターを実装することが決定されました。
[TestMethod] public void ClientStateMachineTest() { // ClientStateMachine var clientStateMachine = new ClientStateMachine(); var xmlDoc = new XmlDocument(); // DGML-, const string fileDgml = @"..\..\SM\Test\ClientStateMachineGraph.dgml"; xmlDoc.Load(fileDgml); var nodeLinks = xmlDoc.SelectSingleNode("/*[local-name()='DirectedGraph']/*[local-name()='Links']"); var nodes = xmlDoc.SelectSingleNode("/*[local-name()='DirectedGraph']/*[local-name()='Nodes']"); if (nodes != null) { nodes.RemoveAll(); foreach (var state in clientStateMachine.StatesCollection) { var newNode = xmlDoc.CreateNode(XmlNodeType.Element, "Node", "http://schemas.microsoft.com/vs/2009/dgml"); var id = xmlDoc.CreateAttribute("Id"); id.Value = state.GetType().Name; var reference = xmlDoc.CreateAttribute("Reference"); reference.Value = string.Format(@"..\..\SM\States\{0}.cs", state.GetType().Name); var background = xmlDoc.CreateAttribute("Background"); background.Value = state.Background.Name; if (newNode.Attributes != null) { newNode.Attributes.Append(id); newNode.Attributes.Append(background); newNode.Attributes.Append(reference); } nodes.AppendChild(newNode); } } if (nodeLinks != null) { nodeLinks.RemoveAll(); foreach (var tr in clientStateMachine.Transitions) { var newLink = xmlDoc.CreateNode(XmlNodeType.Element, "Link", "http://schemas.microsoft.com/vs/2009/dgml"); var source = xmlDoc.CreateAttribute("Source"); source.Value = (tr.Value.InitialState).GetType().Name; var target = xmlDoc.CreateAttribute("Target"); target.Value = tr.Value.FinalState.GetType().Name; if (newLink.Attributes != null) { newLink.Attributes.Append(source); newLink.Attributes.Append(target); } nodeLinks.AppendChild(newLink); } } xmlDoc.Save(fileDgml); }
メソッドの開始時に、プロジェクトDGMLファイルへの相対パスに基づいて、リンクグラフの指向リンクを含むリンクXMLノードと、ノードグラフのノードを含むノードXMLノードが抽出されるXMLドキュメントがロードされます。
さらに、clientStateMachine.StatesCollection状態コレクションに基づいて、グラフの頂点が形成され、状態ファイルと背景色へのリンクが確立されます。
次に、初期InitialState状態と最終FinalState状態を持つclientStateMachine.Transitions遷移テーブルからの各遷移に基づいて、対応するSource属性とTarget属性をLink XML要素に追加することにより、有向グラフエッジが形成されます。
この試験方法の結果を下図に示します。

結論として、私はそれに注意したい:
- グラフレイアウトデザイナを使用して、頂点やリンクが重複または交差しない視覚的なグラフ構造が自動的に取得されました。これは、このVisual Studioツールの優れた利点です。
- グラフの頂点のコンテキストメニューからステータスファイルへのリンクをたどることができます。
- 提示されたジェネレーターは、変換テーブルを持つ任意のステートマシンに簡単に適合できます。
したがって、テストメソッドでの有向グラフジェネレーターのシンプルで効果的な実装が提示され、その実装により、状態図の現在のバージョンを取得できます。