Locked History Actions

guice/Manual/Extensions/Grapher

Grapher

洗練されたアプリケーションを書いたなら、GuiceのリッチなイントロスペクションAPIを使って、 詳細なオブジェクトグラフを記述することができる。 ビルトインのgrapher拡張がこのデータを簡単にビジュアル化してくれる。 複雑なアプリケーションの中の様々なバインディングや依存を統合されたダイアグラムで表示する。

.dotファイルを作成する

Guiceのgrapherは、GraphVizの力を借りている。 オープンソースのグラフビジュアル化パッケージである。 これは、グラフの明細とビジュアル・レイアウトをクリアに分離する。 インジェクタの.dotファイルをグラフ化するには、次のコードを使えばいい。

import com.google.inject.Injector;
import com.google.inject.grapher.GrapherModule;
import com.google.inject.grapher.InjectorGrapher;
import com.google.inject.grapher.graphviz.GraphvizModule;
import com.google.inject.grapher.graphviz.GraphvizRenderer;

public class Grapher {
  private void graph(String filename, Injector demoInjector) throws IOException {
    PrintWriter out = new PrintWriter(new File(filename), "UTF-8");

    Injector injector = Guice.createInjector(new GrapherModule(), new GraphvizModule());
    GraphvizRenderer renderer = injector.getInstance(GraphvizRenderer.class);
    renderer.setOut(out).setRankdir("TB");

    injector.getInstance(InjectorGrapher.class)
        .of(demoInjector)
        .graph();
  }
}

.dotファイル

上のコードを実行すると、グラフ明細を表す.dotファイルが作成される。 ファイルのそれぞれのエントリはグラフ内のノードやエッジを表す。 次に.dotファイルのサンプルを示す。

digraph injector {
  graph [rankdir=TB];
  k_997fdab [shape=box, label=<<table cellspacing="0" cellpadding="5" cellborder="0" border="0"><tr><td 
      align="left" port="header" bgcolor="#ffffff"><font align="left" color="#000000" point-size="10">@Nuclear<br
      align="left"/></font><font color="#000000">EnergySource<br align="left"/></font></td></tr></table>>,
      style=dashed, margin=0.02,0]
  k_119e4fd8 [shape=box, label=<<table cellspacing="0" cellpadding="5" cellborder="0" border="0"><tr><td
      align="left" port="header" bgcolor="#ffffff"><font align="left" color="#000000" point-size="10">@Driver<br 
      align="left"/></font><font color="#000000">Person<br align="left"/></font></td></tr></table>>, 
      style=dashed, margin=0.02,0]
  k_115c9d69 [shape=box, label=<<table cellspacing="0" cellpadding="5" cellborder="0" border="0"><tr><td 
      align="left" port="header" bgcolor="#ffffff"><font color="#000000">FluxCapacitor<br 
      align="left"/></font></td></tr></table>>, style=dashed, margin=0.02,0]
  i_115c9d69 [shape=box, label=<<table cellspacing="0" cellpadding="5" cellborder="1" border="0"><tr><td 
      align="left" port="header" bgcolor="#aaaaaa"><font align="left" color="#ffffff" point-
      size="10">BackToTheFutureModule.java:42<br align="left"/></font><font 
      color="#ffffff">#provideFluxCapacitor(EnergySource)<br align="left"/></font></td></tr></table>>, style=invis, 
      margin=0.02,0]
  k_1c5031a6 [shape=box, label=<<table cellspacing="0" cellpadding="5" cellborder="1" border="0"><tr><td 
      align="left" port="header" bgcolor="#000000"><font color="#ffffff">Plutonium<br 
      align="left"/></font></td></tr><tr><td align="left" port="m_9c5dfb84">&lt;init&gt;</td></tr></table>>, 
      style=invis, margin=0.02,0]
  k_17b87c3a [shape=box, label=<<table cellspacing="0" cellpadding="5" cellborder="1" border="0"><tr><td 
      align="left" port="header" bgcolor="#000000"><font color="#ffffff">MartyMcFly<br 
      align="left"/></font></td></tr><tr><td align="left" port="m_8b2cda3d">&lt;init&gt;</td></tr></table>>, 
      style=invis, margin=0.02,0]
  k_9acc501 [shape=box, label=<<table cellspacing="0" cellpadding="5" cellborder="0" border="0"><tr><td 
      align="left" port="header" bgcolor="#ffffff"><font color="#000000">EnergySource<br 
      align="left"/></font></td></tr></table>>, style=dashed, margin=0.02,0]
  k_dd456f9 [shape=box, label=<<table cellspacing="0" cellpadding="5" cellborder="1" border="0"><tr><td 
      align="left" port="header" bgcolor="#000000"><font color="#ffffff">EnergySourceProvider<br 
      align="left"/></font></td></tr><tr><td align="left" port="m_f4b5f9f7">&lt;init&gt;</td></tr></table>>, 
      style=invis, margin=0.02,0]
  k_997fdab -> k_1c5031a6 [arrowtail=none, style=dashed, arrowhead=onormal]
  k_119e4fd8 -> k_17b87c3a [arrowtail=none, style=dashed, arrowhead=onormal]
  k_115c9d69 -> i_115c9d69 [arrowtail=none, style=dashed, arrowhead=onormalonormal]
  i_115c9d69:header:e -> k_9acc501 [arrowtail=none, style=solid, arrowhead=normal]
  k_9acc501 -> k_dd456f9 [arrowtail=none, style=dashed, arrowhead=onormalonormal]
}

.dotファイルをレンダリングする

使用するプラットフォーム向けのGraphvizのビューアをダウンロードし、 .dotファイルをレンダリングしよう。 レンダリングには数分かかるかもしれない。 レンダリングされたグラフをPDFやイメージにエクスポートすることで、共有が簡単になる。

Grapher_screenshot.png

Linux上では、コマンドラインのdotツールを.dotファイルからイメージに変換するのに使うことができる。

  dot -T png my_injector.dot > my_injector.png

このツールは現在のところ、我々のフォントタグの扱いに問題があることがわかっている。 我々はこの問題を解消中である。

グラフ表示

エッジ:

  • 実線エッジは実装からタイプへ、その依存を表す。
  • 破線エッジはタイプからその実装へのバインディングを表す。
  • 重複矢印はバインディングあるいは依存からプロバイダを表す。

ノード:

  • 実装タイプは黒の背景で示される。
  • 実装インスタンスは灰の背景で示される。

その他:

  • インジェクションポイントがProvider<Foo>を必要とするならば、GrapherはProviderを省略してFooへの依存のみを示す。

  • grapherはインスタンスのtoString()メソッドを利用して、そのタイトルを表示する。ただし、オブジェクトのデフォルト実装をオーバーライドしている場合のみである。