Complex classes like MetadataCollector 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 MetadataCollector, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
21 | class MetadataCollector |
||
22 | { |
||
23 | /** |
||
24 | * @var DocumentFinder |
||
25 | */ |
||
26 | private $finder; |
||
27 | |||
28 | /** |
||
29 | * @var DocumentParser |
||
30 | */ |
||
31 | private $parser; |
||
32 | |||
33 | /** |
||
34 | * @var CacheProvider |
||
35 | */ |
||
36 | private $cache = null; |
||
37 | |||
38 | /** |
||
39 | * @var bool |
||
40 | */ |
||
41 | private $enableCache = false; |
||
42 | |||
43 | /** |
||
44 | * Bundles mappings local cache container. |
||
45 | * |
||
46 | * @var mixed |
||
47 | */ |
||
48 | // private $mappings = []; |
||
|
|||
49 | |||
50 | /** |
||
51 | * @param DocumentFinder $finder For finding documents. |
||
52 | * @param DocumentParser $parser For reading document annotations. |
||
53 | * @param CacheProvider $cache Cache provider to store the meta data for later use. |
||
54 | */ |
||
55 | public function __construct($finder, $parser, $cache = null) |
||
61 | |||
62 | /** |
||
63 | * Enables metadata caching. |
||
64 | * |
||
65 | * @param bool $enableCache |
||
66 | */ |
||
67 | public function setEnableCache($enableCache) |
||
71 | |||
72 | // public function fetchMappingFromCache($name) |
||
73 | // { |
||
74 | // if ($this->enableCache) { |
||
75 | // $this->mappings[$name] = $this->cache->fetch($name); |
||
76 | // } |
||
77 | // |
||
78 | // if (isset($this->mappings[$name])) { |
||
79 | // return $this->mappings[$name]; |
||
80 | // } |
||
81 | // |
||
82 | // return null; |
||
83 | // } |
||
84 | // |
||
85 | // public function saveMappingToCache($name, $value) |
||
86 | // { |
||
87 | // if ($this->enableCache) { |
||
88 | // $this->cache->save($name, $value); |
||
89 | // } |
||
90 | // |
||
91 | // $this->mappings[$name] = $value; |
||
92 | // } |
||
93 | |||
94 | /** |
||
95 | * Fetches bundles mapping from documents. |
||
96 | * |
||
97 | * @param string[] $bundles Elasticsearch manager config. You can get bundles list from 'mappings' node. |
||
98 | * @return array |
||
99 | */ |
||
100 | public function getMappings(array $bundles) |
||
125 | |||
126 | /** |
||
127 | * Searches for documents in the bundle and tries to read them. |
||
128 | * |
||
129 | * @param string $name |
||
130 | * @param array $config Bundle configuration |
||
131 | * |
||
132 | * @return array Empty array on containing zero documents. |
||
133 | */ |
||
134 | public function getBundleMapping($name, $config = []) |
||
199 | |||
200 | /** |
||
201 | * @param array $manager |
||
202 | * |
||
203 | * @return array |
||
204 | */ |
||
205 | public function getManagerTypes($manager) |
||
211 | |||
212 | /** |
||
213 | * Resolves Elasticsearch type by document class. |
||
214 | * |
||
215 | * @param string $className FQCN or string in AppBundle:Document format |
||
216 | * |
||
217 | * @return string |
||
218 | */ |
||
219 | public function getDocumentType($className) |
||
225 | |||
226 | /** |
||
227 | * Retrieves prepared mapping to sent to the elasticsearch client. |
||
228 | * |
||
229 | * @param array $bundles Manager config. |
||
230 | * |
||
231 | * @return array|null |
||
232 | */ |
||
233 | public function getClientMapping(array $bundles) |
||
257 | |||
258 | /** |
||
259 | * Prepares analysis node for Elasticsearch client. |
||
260 | * |
||
261 | * @param array $bundles |
||
262 | * @param array $analysisConfig |
||
263 | * |
||
264 | * @return array |
||
265 | */ |
||
266 | public function getClientAnalysis(array $bundles, $analysisConfig = []) |
||
316 | |||
317 | /** |
||
318 | * Prepares analysis node content for Elasticsearch client. |
||
319 | * |
||
320 | * @param string $type Node type: filter, tokenizer or char_filter |
||
321 | * @param array $analyzer Analyzer from which used helpers will be extracted. |
||
322 | * @param array $analysisConfig Pre configured analyzers container |
||
323 | * @param array $container Current analysis container where prepared helpers will be appended. |
||
324 | * |
||
325 | * @return array |
||
326 | */ |
||
327 | private function getAnalysisNodeConfiguration($type, $analyzer, $analysisConfig, $container = []) |
||
344 | |||
345 | /** |
||
346 | * Gathers annotation data from class. |
||
347 | * |
||
348 | * @param \ReflectionClass $reflectionClass Document reflection class to read mapping from. |
||
349 | * |
||
350 | * @return array |
||
351 | * @throws DocumentParserException |
||
352 | */ |
||
353 | private function getDocumentReflectionMapping(\ReflectionClass $reflectionClass) |
||
357 | |||
358 | /** |
||
359 | * Returns single document mapping metadata. |
||
360 | * |
||
361 | * @param string $namespace Document namespace |
||
362 | * |
||
363 | * @return array |
||
364 | * @throws DocumentParserException |
||
365 | */ |
||
366 | public function getMapping($namespace) |
||
379 | |||
380 | /** |
||
381 | * Adds metadata information to the cache storage. |
||
382 | * |
||
383 | * @param string $bundle |
||
384 | * @param array $mapping |
||
385 | */ |
||
386 | private function cacheBundle($bundle, array $mapping) |
||
393 | |||
394 | /** |
||
395 | * Returns fully qualified class name. |
||
396 | * |
||
397 | * @param string $className |
||
398 | * |
||
399 | * @return string |
||
400 | */ |
||
401 | public function getClassName($className) |
||
405 | } |
||
406 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.