Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
100.00% |
1 / 1 |
|
100.00% |
2 / 2 |
CRAP | |
100.00% |
17 / 17 |
| SpaghettiCoupling | |
100.00% |
1 / 1 |
|
100.00% |
2 / 2 |
8 | |
100.00% |
17 / 17 |
| setFilterPath(Strategy\Search $strategy) | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| generateCoupledClassGraph() | |
100.00% |
1 / 1 |
7 | |
100.00% |
15 / 15 |
|||
| <?php | |
| /* | |
| * Mondrian | |
| */ | |
| namespace Trismegiste\Mondrian\Analysis; | |
| use Trismegiste\Mondrian\Transform\Vertex\ImplVertex; | |
| use Trismegiste\Mondrian\Transform\Vertex\MethodVertex; | |
| use Trismegiste\Mondrian\Transform\Vertex\ClassVertex; | |
| use Trismegiste\Mondrian\Transform\Vertex\InterfaceVertex; | |
| use Trismegiste\Mondrian\Graph\Edge; | |
| use Trismegiste\Mondrian\Graph\BreadthFirstSearch; | |
| /** | |
| * SpaghettiCoupling is an analyser which finds coupling between classes, | |
| * | |
| * How ? | |
| * This analyser searches path between two classes through calls of public | |
| * methods, inheritance or instanciation. | |
| * | |
| * The language I used for representing source code into a digraph was | |
| * created especially to show that. | |
| * | |
| * Note 1 : This service creates a new digraph by selecting only the class | |
| * vertices because with the implementations, there are too many vertices. | |
| * The goal of the digraph is the "search for bridges". This is a concept | |
| * in graph theory where two highly connected graphs are linked by only one | |
| * edge. By cuting this edge (by adding an interface for example), you can | |
| * easily break your "monolith of code" into two pieces. | |
| * | |
| * Note 2 : since I only analyse public methods, I knowingly miss some | |
| * connections. I state that it is not an issue now. If there is a new | |
| * instance in a protected method, this an "inner refactoring" not a refactoring | |
| * of the structure of public implementations. | |
| * | |
| * In a second time, you can refactor this coupling later because you have | |
| * more freedom to change that : you are in a class, there is no coupling outside, | |
| * or perhaps it's ok (factory method pattern for example). Remember, the purpose | |
| * of this service is to help you to "break a monolith" you barely know, | |
| * not to replace your coding skills. There is no magic for that. | |
| * | |
| * There are more immportant issues with cycles of components for example. | |
| * | |
| */ | |
| class SpaghettiCoupling extends BreadthFirstSearch | |
| { | |
| protected $strategy = null; | |
| /** | |
| * Set the strategy to reduce the graph by shortening a path between 2 | |
| * components | |
| * | |
| * @param Strategy\Search $strategy | |
| */ | |
| public function setFilterPath(Strategy\Search $strategy) | |
| { | |
| $this->strategy = $strategy; | |
| } | |
| /** | |
| * Generate a digraph reduced to all concrete coupled classes | |
| */ | |
| public function generateCoupledClassGraph() | |
| { | |
| if (is_null($this->strategy)) { | |
| throw new \LogicException('No defined strategy'); | |
| } | |
| $vSet = $this->graph->getVertexSet(); | |
| foreach ($vSet as $src) { | |
| if ($src instanceof ClassVertex) { | |
| foreach ($vSet as $dst) { | |
| if (($dst instanceof ClassVertex) && ($dst !== $src)) { | |
| $this->resetVisited(); | |
| $path = $this->searchPath($src, $dst); | |
| $this->strategy->collapseEdge($src, $dst, $path); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| /* | |
| private function generateCoupledClassGraph2() | |
| { | |
| $reducedGraph = new \Trismegiste\Mondrian\Graph\Digraph(); | |
| $vSet = $this->graph->getVertexSet(); | |
| $topo = new \Trismegiste\Mondrian\Graph\FloydWarshall($this->graph); | |
| $matrix = $topo->getDistance(); | |
| foreach ($vSet as $line => $src) { | |
| if ($src instanceof ClassVertex) { | |
| foreach ($vSet as $column => $dst) { | |
| if ($dst instanceof ClassVertex) { | |
| if ($matrix->get($line, $column) > 0) { | |
| $reducedGraph->addEdge($src, $dst); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| return $reducedGraph; | |
| }*/ | |
| } |