Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Backend often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Backend, and based on these observations, apply Extract Interface, too.
| 1 | <?php declare(strict_types=1); |
||
| 28 | final class Backend extends Broker\Backend\Memory implements BackendInterface |
||
|
|
|||
| 29 | { |
||
| 30 | /** |
||
| 31 | * @var ClassReflectionInterface[][] |
||
| 32 | */ |
||
| 33 | private $allClasses = [ |
||
| 34 | self::TOKENIZED_CLASSES => [], |
||
| 35 | self::INTERNAL_CLASSES => [], |
||
| 36 | self::NONEXISTENT_CLASSES => [] |
||
| 37 | ]; |
||
| 38 | |||
| 39 | /** |
||
| 40 | * @var mixed[] |
||
| 41 | */ |
||
| 42 | private $declared = []; |
||
| 43 | |||
| 44 | /** |
||
| 45 | * @var ReflectionFactoryInterface |
||
| 46 | */ |
||
| 47 | private $reflectionFactory; |
||
| 48 | 138 | ||
| 49 | public function __construct(ReflectionFactoryInterface $reflectionFactory) |
||
| 53 | |||
| 54 | /** |
||
| 55 | * @return ConstantReflectionInterface[] |
||
| 56 | 131 | */ |
|
| 57 | public function getConstants(): array |
||
| 63 | |||
| 64 | /** |
||
| 65 | * @return FunctionReflectionInterface[] |
||
| 66 | 131 | */ |
|
| 67 | public function getFunctions(): array |
||
| 73 | |||
| 74 | /** |
||
| 75 | * @return ClassReflectionInterface[] |
||
| 76 | 131 | */ |
|
| 77 | protected function parseClassLists(): array |
||
| 120 | |||
| 121 | 131 | /** |
|
| 122 | * Processes a function/method and adds classes from annotations to the overall class array. |
||
| 123 | * |
||
| 124 | * @param ReflectionMethod|ReflectionFunction $reflection |
||
| 125 | */ |
||
| 126 | private function processFunction($reflection): void |
||
| 140 | |||
| 141 | /** |
||
| 142 | 116 | * @return false|void |
|
| 143 | */ |
||
| 144 | private function addClass(string $name) |
||
| 170 | |||
| 171 | /** |
||
| 172 | * @param TokenReflection\ReflectionClass|TokenReflection\Invalid\ReflectionClass $reflection |
||
| 173 | 126 | */ |
|
| 174 | private function loadParentClassesAndInterfacesFromClassReflection($reflection): void |
||
| 190 | |||
| 191 | private function isClassLoaded(string $name): bool |
||
| 197 | |||
| 198 | 116 | /** |
|
| 199 | * @param ClassReflectionInterface|MethodReflectionInterface $reflection |
||
| 200 | 116 | * @param mixed[] $annotations |
|
| 201 | 116 | * @param string $name |
|
| 202 | */ |
||
| 203 | private function loadAnnotationFromReflection($reflection, array $annotations, $name): void |
||
| 219 | 108 | ||
| 220 | /** |
||
| 221 | 108 | * @param string $name |
|
| 222 | * @param ClassReflectionInterface|MethodReflectionInterface|InNamespaceInterface $reflection |
||
| 223 | 108 | */ |
|
| 224 | 108 | private function getClassFqn(string $name, $reflection): string |
|
| 232 | } |
||
| 233 |