Pull to refresh

Визуализация связей внутри класса с помощью GraphViz

Reading time2 min
Views7.2K
Прочитав книжку Р. Мартина «Чистый код», я исполнился решимостью и принялся за рефакторинг своего старого, большого и грязного проекта.

И захотелось мне посмотреть, как в одном из самых простых классов связаны между собой методы и поля. PhpCallGraph, быстро нагугленный, наладить не удалось (какие-то проблемы с xdebug), и к тому же, судя по примерам, он показывает связи во всём проекте, трассируя его, а мне нужно было исследовать один класс.

Я решил написать собственное решение, и вот что получилось.

Скачать код для экспериментов, понадобится GraphViz.

Использовать его очень просто:
Для начала проанализируем сам класс рисовальщика.
require "Class2GV.php";

$c2g = new Class2GV("C:\\Program Files\\GraphViz 2.28\\bin"); //да, я сейчас под виндой
$c2g->showVariables(true); //вообще-то это не нужно, это свойство истинно по умолчанию
$svg = $c2g->convert("Class2GV.php", "dot"); //по умолчанию используется dot, можно не указывать

header("Content-type: image/svg+xml");
readfile($svg);


Class2GV.png


Зелёные прямоугольники — общедоступные методы, жёлтоватые ромбы — защищённые (здесь их нет), красные эллипсы — приватные, голубые прямоугольники — неописанные (унаследованные или динамически вызываемые, их здесь тоже нет). Серые прямоугольники — переменные.
Использование переменных всегда отображается одной стрелкой, вызовы методов — в зависимости от их количества.

Налицо довольно сложная, хотя и вполне логичная структура класса. Кстати, более «правильные» классы хорошо выглядят именно при использовании dot (пытается нарисовать граф иерархически), а более хаотичные лучше располагаются neato или fdp/sfdp(не учитывает направления стрелок).

Однако, если рассмотреть повнимательнее, видно, что справа выделяется довольно связная область, относящаяся к разбору PHP-файла (с помощью встроенной функции get_all_tokens()), и можно бы её и выделить в отдельный класс. Особенно хорошо это видно на графе без переменных.
Class2GV_wv.png


Настолько оптимизировать я не стал, но если бы класс стал разрастаться, это бы пришлось сделать.

Вот ещё несколько примеров классов.
  • Модуль MySQL из Kohana 3.0 (modules/database/classes/kohana/database/mysql.php), замечательный класс.
    mysql.png
  • А вот это Idiorm, простой ORM всё-в-одном, это видно очень хорошо (рисовано neato)
    idiorm.png
  • Какой-то класс из phpBB 3.0 (includes/functions_module.php), рисовано sfdp, c и без переменных класса.
    functions_module.png   functions_module_wv.png
    Мне внутренности phpBB и так не нравились, а теперь ещё и наглядно видно, что это класс слишком за многое отвечает (смотри главу 10 книги «Чистый код») и совершенно ничего не скрывает. Получается, это всего лишь собранные вместе функции, относящиеся примерно к одной области.
  • А это тот класс, для которого создавалось:
    timer.class.png
Tags:
Hubs:
+37
Comments19

Articles

Change theme settings