UML::Class::Simple で Catalyst のクラス継承図を描いてみた

UML::Class::Simple ってモジュールがあります。このモジュールを使うと既存のプログラムを解析してクラス図を作成することができます。業務で仕様書を書く必要がでた場合、もしくは Catalyst のようなフレームワークをより深く知りたくなったときなどに大いに役立つモジュールです。

http://search.cpan.org/~agent/UML-Class-Simple/lib/UML/Class/Simple.pm

UML::Class::Simple is a Perl CPAN module that generates UML class diagrams (PNG format, GIF format, XMI format, or dot source) automatically from Perl 5 source or Perl 5 runtime.
Perl developers can use this module to obtain pretty class diagrams for arbitrary existing Perl class libraries (including modern perl OO modules based on Moose.pm), by only a single command. Companies can also use the resulting pictures to visualize the project hierarchy and embed them into their documentation.
The users no longer need to drag a mouse on the screen so as to draw figures themselves or provide any specs other than the source code of their own libraries that they want to depict. This module does all the jobs for them! :)
Methods created on-the-fly (in BEGIN or some such) can be inspected. Accessors created by modules Class::Accessor, Class::Accessor::Fast, and Class::Accessor::Grouped are recognized as "properties" rather than "methods". Intelligent distingishing between Perl methods and properties other than that is not provided.
You know, I was really impressed by the outputs of UML::Sequence, so I decided to find something to (automatically) get pretty class diagrams too. The images from Autodia's Graphviz backend didn't quite fit my needs when I was making some slides for my presentations.
I think most of the time you just want to use the command-line utility umlclass.pl offered by this module (just like me). See the documentation of umlclass.pl for details.

というわけで手始めに UML::Class::Simple を使って Catalyst のクラス図を作ってみたました。

- スポンサーリンク -

僕自身 UML 2.0 について全然詳しくないのですが、UML のクラス図としては以下のような要素があり、

  • クラス
    クラスは四角形で記述し、内部に、上段からクラス名、属性、操作を表す
  • 関連(リンク)
    クラスから作成されるオブジェクト間の関係を表す。誘導可能性、多重度、関連名とロール名が含まれる。
  • 集約
    オブジェクト間に全体と部分の関係があることを表す。オブジェクトのライフサイクルが一致しない。
  • コンポジション
    全体側と部分側の結びつきがとくに強い集約を表す。オブジェクトのライフサイクルが一致する。
  • 汎化
    クラスの継承関係を表す。サブクラス→スーパークラスの関係を汎化という。
  • 依存
    定義されている要素間に、片方を変更すればもう片方に変更が生じる依存が存在することを表す。
  • インターフェース
    クラスが外部に公開する操作の集合を表す。インターフェイスはそれ自身がインスタンス化されることはない。

UML::Class::Simple で自動生成できるのは、「クラス」と「汎化・特化(継承関係)」の2つです。随分と前置きが長くなりましたが、Catalyst のクラス図はこんな感じになりました。Catalyst:: のモジュールだけに限定して描画しても 4631 x 4555 の巨大なクラス図です。

catalyst01.png

もっとも PNG 出力したのでは、ここから先扱いづらいので、XMI 形式で出力して ArgoUML にインポートしてアレコレするとこんな感じになります。

CatalystClassDiagram.png

僕自身 Catalyst のクラス図(継承図)をはじめてみましたが、Catalyst がどんな構造になっているのか、これだけで随分把握しやすくなります。ホントは、これに関連を記述したいのですが、UML::Class::Simple にまだその機能はありません。といっても、XMI 出力もプロパティ項目の出力ロジックがなかったりとかしたので、勝手に機能追加したり貪ったので、そのうち関連も記述できるように patch 描いてみたいと思います。

最後に、この Catalyst のクラス図を描くまでの手順を残しておきたいと思います。

1. Graphviz - Graph Visualization Software のインストール

cd /usr/local/src/
wget http://www.graphviz.org/pub/graphviz/stable/SOURCES/graphviz-2.22.0.tar.gz
tar xvfz graphviz-2.22.0.tar.gz
cd graphviz-2.22.0
./configure
make
make check
make install

swig のバージョン違いでコンパイルできない場合は RPM でいれちゃう。x86_64 環境の場合。

cd /usr/local/src/
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/x86_64/os/graphviz-2.20.3-1.el4.x86_64.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/x86_64/os/graphviz-devel-2.20.3-1.el4.x86_64.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/x86_64/os/graphviz-doc-2.20.3-1.el4.x86_64.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/x86_64/os/graphviz-gd-2.20.3-1.el4.x86_64.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/x86_64/os/graphviz-graphs-2.20.3-1.el4.x86_64.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/x86_64/os/graphviz-guile-2.20.3-1.el4.x86_64.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/x86_64/os/graphviz-perl-2.20.3-1.el4.x86_64.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/x86_64/os/graphviz-python-2.20.3-1.el4.x86_64.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/x86_64/os/graphviz-ruby-2.20.3-1.el4.x86_64.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/x86_64/os/graphviz-tcl-2.20.3-1.el4.x86_64.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/x86_64/os/webdot-2.16-1.el4.noarch.rpm

rpm -ivh graphviz-2.20.3-1.el4.x86_64.rpm
rpm -ivh graphviz-devel-2.20.3-1.el4.x86_64.rpm
rpm -ivh graphviz-doc-2.20.3-1.el4.x86_64.rpm
rpm -ivh graphviz-gd-2.20.3-1.el4.x86_64.rpm
rpm -ivh graphviz-graphs-2.20.3-1.el4.x86_64.rpm
rpm -ivh graphviz-guile-2.20.3-1.el4.x86_64.rpm
rpm -ivh graphviz-perl-2.20.3-1.el4.x86_64.rpm 
rpm -ivh webdot-2.16-1.el4.noarch.rpm

i386 環境の場合はこちら。

cd /usr/local/src/
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/i386/os/graphviz-2.20.3-1.el4.i386.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/i386/os/graphviz-devel-2.20.3-1.el4.i386.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/i386/os/graphviz-doc-2.20.3-1.el4.i386.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/i386/os/graphviz-gd-2.20.3-1.el4.i386.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/i386/os/graphviz-graphs-2.20.3-1.el4.i386.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/i386/os/graphviz-guile-2.20.3-1.el4.i386.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/i386/os/graphviz-perl-2.20.3-1.el4.i386.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/i386/os/graphviz-python-2.20.3-1.el4.i386.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/i386/os/graphviz-ruby-2.20.3-1.el4.i386.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/i386/os/graphviz-tcl-2.20.3-1.el4.i386.rpm
wget http://www.graphviz.org/pub/graphviz/stable/redhat/el4/i386/os/webdot-2.16-1.el4.noarch.rpm

rpm -ivh graphviz-2.20.3-1.el4.i386.rpm
rpm -ivh graphviz-devel-2.20.3-1.el4.i386.rpm
rpm -ivh graphviz-doc-2.20.3-1.el4.i386.rpm
rpm -ivh graphviz-gd-2.20.3-1.el4.i386.rpm
rpm -ivh graphviz-graphs-2.20.3-1.el4.i386.rpm
rpm -ivh graphviz-guile-2.20.3-1.el4.i386.rpm
rpm -ivh graphviz-perl-2.20.3-1.el4.i386.rpm 
rpm -ivh webdot-2.16-1.el4.noarch.rpm

rpm -ivh webdot-2.16-1.el4.noarch.rpm が何故だかエラーになるので今度は source からコンパイル。

cd /usr/local/src/
wget http://www.graphviz.org/pub/graphviz/stable/SOURCES/webdot-2.22.tar.gz
tar xvfz webdot-2.22.tar.gz
cd webdot-2.22
./configure
make
make install

2. UML::Class::Simple のインストール

cpan> install UML::Class::Simple

3. Catalyst 5.71000 のインストール

perl -MCPAN -e 'install Bundle::CPAN'
perl -MCPAN -e 'install CPAN::Modulelist'

wget http://www.shadowcat.co.uk/static/cat-install 
perl cat-install

なのだが、これだけですんなり入らなかったので、あれやこれやと手動でインストール。やっぱ Catalyst のインストールはすげぇー面倒くさい。

4. MyApp の作成

catalyst.pl MyApp

5. Catalyst のクラス図を描く PNG 編

モジュール名が Catalyst のもののみ抜粋版

perl -I lib /usr/local/bin/umlclass.pl -M MyApp -o catalyst.png -p "^(MyApp|Catalyst)"

モジュール名が Catalyst とある程度の継承がありそうなもののみ抜粋版

perl -I lib /usr/local/bin/umlclass.pl -M MyApp -o catalyst.png -p "^(MyApp|Catalyst|Class|CGI)"

完全版(※激しく時間がかかるし、できあがる画像サイズが 37229 x 10189 とバカでかい)

perl -I lib /usr/local/bin/umlclass.pl -M MyApp -o catalyst.png -p "^[A-Z]"

6. Catalyst のクラス図を描く XMI 編

モジュール名が Catalyst のもののみ抜粋版

perl -I lib /usr/local/bin/umlclass.pl -M MyApp -o catalyst.xmi -p "^(MyApp|Catalyst)"

モジュール名が Catalyst とある程度の継承がありそうなもののみ抜粋版

perl -I lib /usr/local/bin/umlclass.pl -M MyApp -o catalyst.xmi -p "^(MyApp|Catalyst|Class|CGI)"

完全版(※激しく時間がかかる)

perl -I lib /usr/local/bin/umlclass.pl -M MyApp -o catalyst.xmi -p "^[A-Z]"
ちなみに生成された画像はこちらからどうぞ。

7. オープンソースの ArgoUML をインストール

Download ArgoUML 0.26.2 (Windows) をダウンロードしてインストール
argouml.png

8. ArgoUML で catalyst.xmi をインポートして見やすく配置する

argouml02.png

配置を考えたファイルはこちらからどうぞ。

最後に UML::Class::Simple で XMI 出力すると、プロパティを出力してくれなかったのと、Class::Accessor 部分のアクセッサ判定(get/set)が誤判定される場合があったので、Class::Accessor 使っていても get/set をメソッドとして処理するように変更したソースを晒しておきます。

改変したソースのダウンロードはこちらから。

こんな手順で既存のいろいろなプログラムを UML::Class::Simple と同梱される umlclass.pl を使ってクラス継承図を簡単に図示化することができます。

- スポンサーリンク -