Die einfachste und schnellste Methode ein bestehendes System zu visualisieren liegt in der Auswertung der Membervariablen jeglicher Klasse und die Erzeugung eines gerichteten Graphen. Natürlich werden hier Objekte die per Übergabe in Methoden verwendet werden nicht betrachtet sowie auch Singleton Klassen auf die man über die static Methoden zugreift. Aber wie gesagt, die Vorgehensweise verschafft einen ersten Einblick.
Das Resultat zum nachfolgenden Beispiel:
Dabei wird mit Hilfe von Reflection und Graphviz einem Tool zur grafischen Darstellung von Hierarchien und Netzwerken ein Architekturbild im gewünschten Format erzeugen. Graphviz eignet sich vor allem deswegen, weil ab einer gewissen größe eines System, das manuelle Layout nicht mehr einfach ist. Die Layoutalgorithmen von Graphviz können auch mehr als 100 oder 1000 Knoten noch immer transparent darstellen.
Folgende Vorgehensweise wird hier durchgeführt:
- Auslesen aller Klassen eines definierten Source-Verzeichnisses.
- Über eine Schleife werden alle MemberVariablen über die Methode
classloader.loadClass(name).getDeclaredFields()
ausgelesen. - Jeder Schleifendurchlauf schreibt die Memeberbeziehung zu einer anderen Klasse in ein DOT-File (Graphvizformat)<./li>
Drei Klassen, wobei jede die anderen kennt.
1:public class Class1 {
2: private Class2 class2;
3: private Class3 class3;
4:}
5:
6:public class Class2 {
7: private Class1 class1;
8: private Class3 class3;
9:}
10:
11:public class Class3 {
12: private Class2 class2;
13: private Class1 class1;
14:}
1:package org.developersblog.PragmaticVisualizeArchiteture;
2:
3:import java.io.File;
4:import java.io.FileWriter;
5:import java.io.IOException;
6:import java.lang.reflect.Field;
7:import java.util.ArrayList;
8:import java.util.List;
9:
10:public class MemberExtractionAndDotGeneration {
11:
12: public static void getClassNames(String prefix,
13: List<String> classnames,
14: String dir) {
15: File dirFile = new File(dir);
16: for (File file : dirFile.listFiles()) {
17: if (file.isDirectory()) {
18: if (prefix.length() > 0) {
19: getClassNames(prefix + "." +
20: file.getName(),
21: classnames,
22: file.getAbsolutePath());
23: } else {
24: getClassNames(file.getName(), classnames,
25: file.getAbsolutePath());
26: }
27: } else {
28: if (file.getName().endsWith(".java")) {
29: if (prefix.length() > 0) {
30: String name = prefix + "." + file.getName().
31: replaceAll(".java", "");
32: classnames.add(name);
33: } else {
34: String name =
35: file.getName().replaceAll(".java", "");
36: classnames.add(name);
37: }
38: }
39: }
40: }
41: }
42:
43: /**
44: * @param args
45: * @throws ClassNotFoundException
46: * @throws SecurityException
47: * @throws IOException
48: */
49: public static void main(String[] args) throws SecurityException,
50: ClassNotFoundException, IOException {
51: FileWriter writer = new FileWriter(new File(
52: "/home/rafsob/Desktop/graph.dot"));
53: writer.write("digraph G {\r\nedge [len=2];\r\n");
54: ClassLoader cl = MemberExtractionAndDotGeneration.
55: class.getClassLoader();
56: List<String> classnames = new ArrayList<String>();
57: //Klassen aus dem src Verzeichnis holen
58: getClassNames("", classnames,
59: "/home/rafsob/Desktop/workspace/" +
60: "PragmaticVisualizeArchiteture/src/main/java");
61: //Klassenreferenzen identifizieren
62: for (String name : classnames) {
63: System.out.println("check class with name: " + name);
64: for (Field field : cl.loadClass(name).getDeclaredFields()) {
65: if (classnames.contains(field.getType().getCanonicalName()) &&
66: !name.equals(field.getType().getCanonicalName())) {
67:
68: int lastFirst = name.lastIndexOf('.');
69: int lastSecond = field.getType().
70: getCanonicalName().lastIndexOf('.');
71: //Knotenbeziehung in DOT defnieren
72: writer.write(" \"" + name.substring(lastFirst + 1) + "\" -> \"" +
73: field.getType().getCanonicalName().
74: substring(lastSecond + 1) + "\";\r\n");
75: }
76: }
77: }
78: writer.write("}");
79: writer.close();
80: //Neato für die Darstellung von Graphen starten
81: Process p = Runtime.getRuntime().exec(
82: "/usr/bin/neato " +
83: "-Tpng /home/rafsob/Desktop/graph.dot " +
84: "-o /home/rafsob/Desktop/graph.png");
85: System.out.println("end");
86: }
87:}
88:
89:
Technorati Tags: Architektur Architekturanalyse
