Complex classes like ResourceGenerator 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 ResourceGenerator, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
28 | class ResourceGenerator extends AbstractGenerator |
||
29 | { |
||
30 | /** |
||
31 | * @private Filesystem |
||
32 | */ |
||
33 | private $filesystem; |
||
34 | |||
35 | /** |
||
36 | * @private HttpKernelInterface |
||
37 | */ |
||
38 | private $kernel; |
||
39 | |||
40 | /** |
||
41 | * our json file definition |
||
42 | * |
||
43 | * @var JsonDefinition|null |
||
44 | */ |
||
45 | private $json = null; |
||
46 | |||
47 | /** |
||
48 | * @var ArrayCollection |
||
49 | */ |
||
50 | protected $xmlParameters; |
||
51 | |||
52 | /** |
||
53 | * @var \DomDocument |
||
54 | */ |
||
55 | private $serviceDOM; |
||
56 | |||
57 | /** |
||
58 | * @var FieldMapper |
||
59 | */ |
||
60 | private $mapper; |
||
61 | |||
62 | /** |
||
63 | * @var boolean |
||
64 | */ |
||
65 | private $generateController = false; |
||
66 | |||
67 | /** |
||
68 | * @var ParameterBuilder |
||
69 | */ |
||
70 | private $parameterBuilder; |
||
71 | |||
72 | /** |
||
73 | * Instantiates generator object |
||
74 | * |
||
75 | * @param Filesystem $filesystem fs abstraction layer |
||
76 | * @param HttpKernelInterface $kernel app kernel |
||
77 | * @param FieldMapper $mapper field type mapper |
||
78 | * @param ParameterBuilder $parameterBuilder param builder |
||
79 | */ |
||
80 | 2 | public function __construct( |
|
92 | |||
93 | /** |
||
94 | * @param JsonDefinition $json optional JsonDefinition object |
||
95 | * |
||
96 | * @return void |
||
97 | */ |
||
98 | public function setJson(JsonDefinition $json) |
||
102 | |||
103 | /** |
||
104 | * @param boolean $generateController should the controller be generated or not |
||
105 | * |
||
106 | * @return void |
||
107 | */ |
||
108 | public function setGenerateController($generateController) |
||
112 | |||
113 | /** |
||
114 | * generate the resource with all its bits and parts |
||
115 | * |
||
116 | * @param BundleInterface $bundle bundle |
||
117 | * @param string $document document name |
||
118 | * @param string $format format of config files (please use xml) |
||
119 | * @param array $fields fields to add |
||
120 | * |
||
121 | * @return EntityGeneratorResult |
||
122 | */ |
||
123 | public function generate( |
||
182 | |||
183 | /** |
||
184 | * Writes the current services definition to a file. |
||
185 | * |
||
186 | * @param string $dir base bundle dir |
||
187 | * |
||
188 | * @return void |
||
189 | */ |
||
190 | 8 | protected function persistServicesXML($dir) |
|
196 | |||
197 | /** |
||
198 | * generate document part of a resource |
||
199 | * |
||
200 | * @param array $parameters twig parameters |
||
201 | * @param string $dir base bundle dir |
||
202 | * @param string $document document name |
||
203 | * |
||
204 | * @return void |
||
205 | */ |
||
206 | 6 | protected function generateDocument($parameters, $dir, $document) |
|
246 | |||
247 | /** |
||
248 | * update xml services |
||
249 | * |
||
250 | * @param array $parameters twig parameters |
||
251 | * @param string $dir base bundle dir |
||
252 | * @param string $document document name |
||
253 | * |
||
254 | * @return void |
||
255 | */ |
||
256 | 6 | protected function generateServices($parameters, $dir, $document) |
|
257 | { |
||
258 | 6 | $services = $this->loadServices($dir); |
|
259 | |||
260 | 6 | $bundleParts = explode('\\', $parameters['base']); |
|
261 | 6 | $shortName = $bundleParts[0]; |
|
262 | 6 | $shortBundle = $this->getBundleBaseName($bundleParts[1]); |
|
263 | |||
264 | 6 | $docName = implode( |
|
265 | 6 | '.', |
|
266 | array( |
||
267 | 6 | strtolower($shortName), |
|
268 | 6 | strtolower($shortBundle), |
|
269 | 6 | 'document', |
|
270 | 6 | strtolower($parameters['document']) |
|
271 | ) |
||
272 | ); |
||
273 | |||
274 | 6 | $this->addXMLParameter( |
|
275 | 6 | $parameters['base'] . 'Document\\' . $parameters['document'], |
|
276 | 6 | $docName . '.class' |
|
277 | ); |
||
278 | |||
279 | 6 | $this->addXMLParameter( |
|
280 | 6 | $parameters['json']->getRoles(), |
|
281 | 6 | $docName . '.roles', |
|
282 | 6 | 'collection' |
|
283 | ); |
||
284 | |||
285 | 6 | $services = $this->addService( |
|
286 | 6 | $services, |
|
287 | 6 | $docName |
|
288 | ); |
||
289 | |||
290 | 6 | $repoName = implode( |
|
291 | 6 | '.', |
|
292 | array( |
||
293 | 6 | strtolower($shortName), |
|
294 | 6 | strtolower($shortBundle), |
|
295 | 6 | 'repository', |
|
296 | 6 | strtolower($parameters['document']) |
|
297 | ) |
||
298 | ); |
||
299 | |||
300 | // normal repo service |
||
301 | 6 | $services = $this->addParam( |
|
302 | 6 | $services, |
|
303 | 6 | $repoName . '.class', |
|
304 | 6 | $parameters['base'] . 'Repository\\' . $parameters['document'] |
|
305 | ); |
||
306 | |||
307 | 6 | $this->addService( |
|
308 | 6 | $services, |
|
309 | 6 | $repoName, |
|
310 | 6 | null, |
|
311 | 6 | [], |
|
312 | 6 | null, |
|
313 | array( |
||
314 | array( |
||
315 | 6 | 'type' => 'string', |
|
316 | 6 | 'value' => $parameters['bundle'] . ':' . $document |
|
317 | ) |
||
318 | ), |
||
319 | 6 | 'doctrine_mongodb.odm.default_document_manager', |
|
320 | 6 | 'getRepository' |
|
321 | ); |
||
322 | |||
323 | // embedded repo service |
||
324 | 6 | $services = $this->addParam( |
|
325 | 6 | $services, |
|
326 | 6 | $repoName . 'embedded.class', |
|
327 | 6 | $parameters['base'] . 'Repository\\' . $parameters['document'] . 'Embedded' |
|
328 | ); |
||
329 | |||
330 | 6 | $this->addService( |
|
331 | 6 | $services, |
|
332 | 6 | $repoName . 'embedded', |
|
333 | 6 | null, |
|
334 | 6 | [], |
|
335 | 6 | null, |
|
336 | array( |
||
337 | array( |
||
338 | 6 | 'type' => 'string', |
|
339 | 6 | 'value' => $parameters['bundle'] . ':' . $document . 'Embedded' |
|
340 | ) |
||
341 | ), |
||
342 | 6 | 'doctrine_mongodb.odm.default_document_manager', |
|
343 | 6 | 'getRepository' |
|
344 | ); |
||
345 | |||
346 | 6 | $this->renderFile( |
|
347 | 6 | 'document/DocumentRepository.php.twig', |
|
348 | 6 | $dir . '/Repository/' . $document . 'Repository.php', |
|
349 | 6 | $parameters |
|
350 | ); |
||
351 | 6 | $this->renderFile( |
|
352 | 6 | 'document/DocumentRepository.php.twig', |
|
353 | 6 | $dir . '/Repository/' . $document . 'EmbeddedRepository.php', |
|
354 | 6 | array_merge( |
|
355 | 6 | $parameters, |
|
356 | [ |
||
357 | 6 | 'document' => $document.'Embedded', |
|
358 | ] |
||
359 | ) |
||
360 | ); |
||
361 | |||
362 | 6 | $this->persistServicesXML($dir); |
|
363 | 6 | } |
|
364 | |||
365 | /** |
||
366 | * Generates the parameters section of the services.xml file. |
||
367 | * |
||
368 | * @param string $dir base bundle dir |
||
369 | * |
||
370 | * @return void |
||
371 | */ |
||
372 | 2 | protected function generateParameters($dir) |
|
391 | |||
392 | /** |
||
393 | * Registers information to be generated to a parameter tag. |
||
394 | * |
||
395 | * @param mixed $value Content of the tag |
||
396 | * @param string $key Content of the key attribute |
||
397 | * @param string $type Type of the tag |
||
398 | * |
||
399 | * @return void |
||
400 | */ |
||
401 | 2 | protected function addXmlParameter($value, $key, $type = 'string') |
|
417 | |||
418 | /** |
||
419 | * load services.xml |
||
420 | * |
||
421 | * @param string $dir base dir |
||
422 | * |
||
423 | * @return \DOMDocument |
||
424 | */ |
||
425 | 4 | protected function loadServices($dir) |
|
436 | |||
437 | /** |
||
438 | * add param to services.xml |
||
439 | * |
||
440 | * @param \DOMDocument $dom services.xml document |
||
441 | * @param string $key parameter key |
||
442 | * @param string $value parameter value |
||
443 | * |
||
444 | * @return \DOMDocument |
||
445 | */ |
||
446 | 12 | protected function addParam(\DOMDocument $dom, $key, $value) |
|
460 | |||
461 | /** |
||
462 | * Adds a new parameter tag to parameters section reflecting the defined roles. |
||
463 | * |
||
464 | * @param \DOMDocument $dom services.xml document |
||
465 | * @param string $key parameter key |
||
466 | * @param array $values parameter value |
||
467 | * |
||
468 | * @return void |
||
469 | * |
||
470 | * @link http://symfony.com/doc/current/book/service_container.html#array-parameters |
||
471 | */ |
||
472 | 4 | protected function addCollectionParam(\DomDocument $dom, $key, array $values) |
|
491 | |||
492 | /** |
||
493 | * Determines, if the provided key attribute was already claimed by a parameter node. |
||
494 | * |
||
495 | * @param \DomDocument $dom Current document |
||
496 | * @param string $key Key to be found in document |
||
497 | * |
||
498 | * @return bool |
||
499 | */ |
||
500 | 14 | private function parameterNodeExists(\DomDocument $dom, $key) |
|
507 | |||
508 | /** |
||
509 | * add node if missing |
||
510 | * |
||
511 | * @param \DOMDocument $dom document |
||
512 | * @param string $element name for new node element |
||
513 | * @param string $insertBefore xPath query of the new node shall be added before |
||
514 | * @param string $container name of container tag |
||
515 | * |
||
516 | * @return \DOMNode new element node |
||
517 | */ |
||
518 | 14 | private function addNodeIfMissing(&$dom, $element, $insertBefore = '', $container = 'container') |
|
544 | |||
545 | /** |
||
546 | * add attribute to node if needed |
||
547 | * |
||
548 | * @param string $name attribute name |
||
549 | * @param string $value attribute value |
||
550 | * @param \DOMDocument $dom document |
||
551 | * @param \DOMElement $node parent node |
||
552 | * |
||
553 | * @return void |
||
554 | */ |
||
555 | 14 | private function addAttributeToNode($name, $value, $dom, $node) |
|
563 | |||
564 | /** |
||
565 | * add service to services.xml |
||
566 | * |
||
567 | * @param \DOMDocument $dom services.xml dom |
||
568 | * @param string $id id of new service |
||
569 | * @param string $parent parent for service |
||
570 | * @param array $calls methodCalls to add |
||
571 | * @param string $tag tag name or empty if no tag needed |
||
572 | * @param array $arguments service arguments |
||
573 | * @param string $factoryService factory service id |
||
574 | * @param string $factoryMethod factory method name |
||
575 | * |
||
576 | * @return \DOMDocument |
||
577 | */ |
||
578 | protected function addService( |
||
641 | |||
642 | /** |
||
643 | * add calls to service |
||
644 | * |
||
645 | * @param array $calls info on calls to create |
||
646 | * @param \DOMDocument $dom current domdocument |
||
647 | * @param \DOMElement $node node to add call to |
||
648 | * |
||
649 | * @return void |
||
650 | */ |
||
651 | private function addCallsToService($calls, $dom, $node) |
||
657 | |||
658 | /** |
||
659 | * add call to service |
||
660 | * |
||
661 | * @param array $call info on call node to create |
||
662 | * @param \DOMDocument $dom current domdocument |
||
663 | * @param \DOMElement $node node to add call to |
||
664 | * |
||
665 | * @return void |
||
666 | */ |
||
667 | private function addCallToService($call, $dom, $node) |
||
689 | |||
690 | /** |
||
691 | * add arguments to servie |
||
692 | * |
||
693 | * @param array $arguments arguments to create |
||
694 | * @param \DOMDocument $dom dom document to add to |
||
695 | * @param \DOMElement $node node to use as parent |
||
696 | * |
||
697 | * @return void |
||
698 | */ |
||
699 | private function addArgumentsToService($arguments, $dom, $node) |
||
705 | |||
706 | /** |
||
707 | * add argument to service |
||
708 | * |
||
709 | * @param array $argument info on argument to create |
||
710 | * @param \DOMDocument $dom dom document to add to |
||
711 | * @param \DOMElement $node node to use as parent |
||
712 | * |
||
713 | * @return void |
||
714 | */ |
||
715 | private function addArgumentToService($argument, $dom, $node) |
||
735 | |||
736 | /** |
||
737 | * generate serializer part of a resource |
||
738 | * |
||
739 | * @param array $parameters twig parameters |
||
740 | * @param string $dir base bundle dir |
||
741 | * @param string $document document name |
||
742 | * |
||
743 | * @return void |
||
744 | */ |
||
745 | protected function generateSerializer(array $parameters, $dir, $document) |
||
796 | |||
797 | /** |
||
798 | * generate model part of a resource |
||
799 | * |
||
800 | * @param array $parameters twig parameters |
||
801 | * @param string $dir base bundle dir |
||
802 | * @param string $document document name |
||
803 | * |
||
804 | * @return void |
||
805 | */ |
||
806 | protected function generateModel(array $parameters, $dir, $document) |
||
876 | |||
877 | /** |
||
878 | * generate RESTful controllers ans service configs |
||
879 | * |
||
880 | * @param array $parameters twig parameters |
||
881 | * @param string $dir base bundle dir |
||
882 | * @param string $document document name |
||
883 | * |
||
884 | * @return void |
||
885 | */ |
||
886 | protected function generateController(array $parameters, $dir, $document) |
||
924 | |||
925 | /** |
||
926 | * generates fixtures |
||
927 | * |
||
928 | * @param array $parameters twig parameters |
||
929 | * @param string $dir base bundle dir |
||
930 | * @param string $document document name |
||
931 | * |
||
932 | * @return void |
||
933 | */ |
||
934 | protected function generateFixtures(array $parameters, $dir, $document) |
||
945 | } |
||
946 |
Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code: