Complex classes like StructureMap 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 StructureMap, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
49 | class StructureMap implements MapInterface |
||
50 | { |
||
51 | /** |
||
52 | * @var array $map The actual container for the map |
||
53 | */ |
||
54 | protected $map; |
||
55 | |||
56 | /** |
||
57 | * @var array $rootPaths The $autoloaderPaths and $enforcementPaths combined to build up paths we have to index |
||
58 | */ |
||
59 | protected $rootPaths; |
||
60 | |||
61 | /** |
||
62 | * @var array $enforcementPaths Which paths do we like to include in our map? |
||
63 | */ |
||
64 | protected $autoloaderPaths; |
||
65 | |||
66 | /** |
||
67 | * @var array $enforcementPaths Which paths do we have to enforce |
||
68 | */ |
||
69 | protected $enforcementPaths; |
||
70 | |||
71 | /** |
||
72 | * @var string $mapPath Where will the map be stored? |
||
73 | */ |
||
74 | protected $mapPath; |
||
75 | |||
76 | /** |
||
77 | * @var \AppserverIo\Doppelgaenger\Config $config Configuration |
||
78 | */ |
||
79 | protected $config; |
||
80 | |||
81 | /** |
||
82 | * @var \Iterator|null $projectIterator Will hold the iterator over the project root pathes if needed |
||
83 | */ |
||
84 | protected $projectIterator; |
||
85 | |||
86 | /** |
||
87 | * @var string $version Will hold the version of the currently loaded map |
||
88 | */ |
||
89 | protected $version; |
||
90 | |||
91 | /** |
||
92 | * Default constructor |
||
93 | * |
||
94 | * @param array $autoloaderPaths Which paths do we like to include in our map? |
||
95 | * @param array $enforcementPaths Which paths do we have to enforce |
||
96 | * @param \AppserverIo\Doppelgaenger\Config $config Configuration |
||
97 | */ |
||
98 | public function __construct($autoloaderPaths, $enforcementPaths, Config $config) |
||
129 | |||
130 | /** |
||
131 | * Will return a list of files which are within the enforcementPaths |
||
132 | * |
||
133 | * @return array |
||
134 | */ |
||
135 | protected function getEnforcedFiles() |
||
154 | |||
155 | /** |
||
156 | * Will return all entries within a map. If needed only entries of contracted |
||
157 | * structures will be returned. |
||
158 | * |
||
159 | * @param boolean $annotated Do we only want entries containing useful annotations? |
||
160 | * @param boolean $enforced Do we only want entries which are enforced? |
||
161 | * |
||
162 | * @return mixed |
||
163 | */ |
||
164 | public function getEntries($annotated = false, $enforced = false) |
||
193 | |||
194 | /** |
||
195 | * Will add a structure entry to the map. |
||
196 | * |
||
197 | * @param \AppserverIo\Doppelgaenger\Entities\Definitions\Structure $structure The structure to add |
||
198 | * |
||
199 | * @return bool |
||
200 | */ |
||
201 | public function add(Structure $structure) |
||
216 | |||
217 | /** |
||
218 | * Will return true if there is no map generated by now. False if there are map entries |
||
219 | * |
||
220 | * @return boolean |
||
221 | */ |
||
222 | public function isEmpty() |
||
226 | |||
227 | /** |
||
228 | * Do we have an entry for the given identifier |
||
229 | * |
||
230 | * @param string $identifier The identifier of the entry we try to find |
||
231 | * |
||
232 | * @return bool |
||
233 | */ |
||
234 | public function entryExists($identifier) |
||
238 | |||
239 | /** |
||
240 | * Will fill the structure map according to it's config |
||
241 | * |
||
242 | * @return boolean |
||
243 | */ |
||
244 | public function fill() |
||
255 | |||
256 | /** |
||
257 | * Will update a given structure. |
||
258 | * If the entry does not exist we will create it |
||
259 | * |
||
260 | * @param \AppserverIo\Doppelgaenger\Entities\Definitions\Structure|null $structure The structure to update |
||
261 | * |
||
262 | * @return void |
||
263 | * |
||
264 | * TODO implement this in the implementing classes |
||
|
|||
265 | */ |
||
266 | public function update(Structure $structure = null) |
||
270 | |||
271 | /** |
||
272 | * Will return the entry specified by it's identifier. |
||
273 | * If none is found, false will be returned. |
||
274 | * |
||
275 | * @param string $identifier The identifier of the entry we try to find |
||
276 | * |
||
277 | * @return boolean|\AppserverIo\Doppelgaenger\Entities\Definitions\Structure |
||
278 | */ |
||
279 | public function getEntry($identifier) |
||
300 | |||
301 | /** |
||
302 | * Checks if the entry for a certain structure is recent if one was specified. |
||
303 | * If not it will check if the whole map is recent. |
||
304 | * |
||
305 | * @param null|string $identifier The identifier of the entry we try to find |
||
306 | * |
||
307 | * @return boolean |
||
308 | */ |
||
309 | public function isRecent($identifier = null) |
||
333 | |||
334 | /** |
||
335 | * Will return an array of all entry identifiers which are stored in this map. |
||
336 | * We might filter by entry type |
||
337 | * |
||
338 | * @param string|null $type The type to filter by |
||
339 | * |
||
340 | * @return array |
||
341 | */ |
||
342 | public function getIdentifiers($type = null) |
||
360 | |||
361 | /** |
||
362 | * Will return an array of all files which are stored in this map. |
||
363 | * Will include the full path if $fullPath is true. |
||
364 | * |
||
365 | * @param boolean $fullPath Do we need the full path? |
||
366 | * |
||
367 | * @return array |
||
368 | */ |
||
369 | public function getFiles($fullPath = true) |
||
387 | |||
388 | /** |
||
389 | * Removes an entry from the map of structures. |
||
390 | * |
||
391 | * @param null|string $identifier The identifier of the entry we try to find |
||
392 | * |
||
393 | * @return boolean |
||
394 | */ |
||
395 | public function remove($identifier) |
||
407 | |||
408 | /** |
||
409 | * Will reindex the structure map aka create it anew. |
||
410 | * If $specificPath is supplied we will reindex the specified path only and add it to the map. |
||
411 | * $specificPath MUST be within the root pathes of this StructureMap instance, otherwise it is no REindexing. |
||
412 | * |
||
413 | * @param string|null $specificPath A certain path which will be reindexed |
||
414 | * |
||
415 | * @return boolean |
||
416 | */ |
||
417 | public function reIndex($specificPath = null) |
||
457 | |||
458 | /** |
||
459 | * Will return a "version" of the current project file base by checking the cTime of all directories |
||
460 | * within the project root paths and create a sha1 hash over them. |
||
461 | * |
||
462 | * @return string |
||
463 | */ |
||
464 | protected function findVersion() |
||
478 | |||
479 | /** |
||
480 | * Will Return an iterator over our project files |
||
481 | * |
||
482 | * @return \Iterator |
||
483 | */ |
||
484 | protected function getProjectIterator() |
||
496 | |||
497 | /** |
||
498 | * Will Return an iterator over a set of files determined by a list of directories to iterate over |
||
499 | * |
||
500 | * @param array $paths List of directories to iterate over |
||
501 | * |
||
502 | * @return \Iterator |
||
503 | */ |
||
504 | protected function getDirectoryIterator(array $paths) |
||
531 | |||
532 | |||
533 | /** |
||
534 | * Will generate the structure map within the specified root path. |
||
535 | * |
||
536 | * @return void |
||
537 | */ |
||
538 | protected function generate() |
||
608 | |||
609 | /** |
||
610 | * Check if the file should be enforced by considering three factors: |
||
611 | * 1. does it have contracts? |
||
612 | * 2. is it within the list of enforced files? |
||
613 | * 3. is it within the namespaces omitted of enforcement? |
||
614 | * |
||
615 | * @param string $file The path of the file to be tested |
||
616 | * @param string $fileIdentifier The qualified name of the file's structure |
||
617 | * @param boolean $hasAnnotations Does this file contain contracts (as epr current configuration) |
||
618 | * @param array $enforcedFiles Array of files which need to be enforced |
||
619 | * @param array $omittedNamespaces Array of namespaces which are omitted from the enforcement |
||
620 | * |
||
621 | * @return boolean |
||
622 | */ |
||
623 | protected function isFileEnforced($file, $fileIdentifier, $hasAnnotations, $enforcedFiles, $omittedNamespaces) |
||
641 | |||
642 | /** |
||
643 | * Will return true if the specified file has annotations which might be useful, false if not |
||
644 | * |
||
645 | * @param string $file File to check for contracts |
||
646 | * @param array $annotations Array of annotations to look for |
||
647 | * |
||
648 | * @return boolean |
||
649 | */ |
||
650 | protected function findAnnotations($file, array $annotations) |
||
676 | |||
677 | /** |
||
678 | * Will get the identifier of a structure within a name. |
||
679 | * Identifier will be most likely the qualified name including namespace and structure name. |
||
680 | * May return false on error. |
||
681 | * Will return an ugly array of the sort array(<STRUCTURE_TYPE>, <STRUCTURE_NAME>) |
||
682 | * |
||
683 | * @param string $file The file to check |
||
684 | * |
||
685 | * @return array|boolean |
||
686 | * @throws \Exception|\AppserverIo\Doppelgaenger\Exceptions\ParserException |
||
687 | */ |
||
688 | protected function findIdentifier($file) |
||
772 | |||
773 | /** |
||
774 | * Will load a serialized map from the storage file, if it exists |
||
775 | * |
||
776 | * @return bool |
||
777 | */ |
||
778 | protected function load() |
||
794 | |||
795 | /** |
||
796 | * Will save this map into the storage file. |
||
797 | * |
||
798 | * @return bool |
||
799 | */ |
||
800 | protected function save() |
||
819 | } |
||
820 |