Complex classes like Struct 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 Struct, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
20 | class Struct extends AbstractModelFile |
||
21 | { |
||
22 | /** |
||
23 | * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getClassConstants() |
||
24 | */ |
||
25 | 160 | protected function getClassConstants(ConstantContainer $constants) |
|
28 | /** |
||
29 | * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getConstantAnnotationBlock() |
||
30 | */ |
||
31 | protected function getConstantAnnotationBlock(PhpConstant $constant) |
||
34 | /** |
||
35 | * @param bool $includeInheritanceAttributes include the attributes of parent class, default parent attributes are not included. If true, then the array is an associative array containing and index "attribute" for the StructAttribute object and an index "model" for the Struct object. |
||
36 | * @param bool $requiredFirst places the required attributes first, then the not required in order to have the _contrust method with the required attribute at first |
||
37 | * @return StructAttributeContainer |
||
38 | */ |
||
39 | 160 | protected function getModelAttributes($includeInheritanceAttributes = false, $requiredFirst = true) |
|
43 | /** |
||
44 | * @param PropertyContainer $properties |
||
45 | */ |
||
46 | 195 | protected function getClassProperties(PropertyContainer $properties) |
|
54 | /** |
||
55 | * @return PhpAnnotationBlock $property |
||
56 | */ |
||
57 | 160 | protected function getPropertyAnnotationBlock(PhpProperty $property) |
|
58 | { |
||
59 | 160 | $annotationBlock = new PhpAnnotationBlock(); |
|
60 | 160 | $annotationBlock->addChild(sprintf('The %s', $property->getName())); |
|
61 | 160 | $attribute = $this->getModel()->getAttribute($property->getName()); |
|
62 | 160 | if (!$attribute instanceof StructAttributeModel) { |
|
63 | 5 | $attribute = $this->getModel()->getAttributeByCleanName($property->getName()); |
|
64 | 2 | } |
|
65 | 160 | if ($attribute instanceof StructAttributeModel) { |
|
66 | 160 | $this->defineModelAnnotationsFromWsdl($annotationBlock, $attribute); |
|
67 | 160 | $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_VAR, $this->getStructAttributeTypeSetAnnotation($attribute, true))); |
|
68 | 64 | } |
|
69 | 160 | return $annotationBlock; |
|
70 | } |
||
71 | /** |
||
72 | * @param MethodContainer $methods |
||
73 | */ |
||
74 | 160 | protected function getClassMethods(MethodContainer $methods) |
|
75 | { |
||
76 | 160 | $this->addStructMethodConstruct($methods)->addStructMethodsSetAndGet($methods)->addStructMethodSetState($methods); |
|
77 | 160 | } |
|
78 | /** |
||
79 | * @param MethodContainer $methods |
||
80 | * @return Struct |
||
81 | */ |
||
82 | 160 | protected function addStructMethodConstruct(MethodContainer $methods) |
|
83 | { |
||
84 | 160 | $method = new PhpMethod(self::METHOD_CONSTRUCT, $this->getStructMethodParametersValues()); |
|
85 | 160 | $this->addStructMethodConstructBody($method); |
|
86 | 160 | $methods->add($method); |
|
87 | 160 | return $this; |
|
88 | } |
||
89 | /** |
||
90 | * @param PhpMethod $method |
||
91 | * @return Struct |
||
92 | */ |
||
93 | 160 | protected function addStructMethodConstructBody(PhpMethod $method) |
|
94 | { |
||
95 | 160 | $count = $this->getModelAttributes()->count(); |
|
96 | 160 | foreach ($this->getModelAttributes() as $index => $attribute) { |
|
97 | 160 | if ($index === 0) { |
|
98 | 160 | $method->addChild('$this'); |
|
99 | 64 | } |
|
100 | 160 | $this->addStructMethodConstructBodyForAttribute($method, $attribute, $count - 1 === $index); |
|
101 | 64 | } |
|
102 | 160 | return $this; |
|
103 | } |
||
104 | /** |
||
105 | * @param PhpMethod $method |
||
106 | * @param StructAttributeModel $attribute |
||
107 | * @param bool $isLast |
||
108 | * @return Struct |
||
109 | */ |
||
110 | 160 | protected function addStructMethodConstructBodyForAttribute(PhpMethod $method, StructAttributeModel $attribute, $isLast) |
|
111 | { |
||
112 | 160 | $uniqueString = $attribute->getUniqueString($attribute->getCleanName(), 'method'); |
|
113 | 160 | $method->addChild($method->getIndentedString(sprintf('->%s($%s)%s', $attribute->getSetterName(), lcfirst($uniqueString), $isLast ? ';' : ''), 1)); |
|
114 | 160 | return $this; |
|
115 | } |
||
116 | /** |
||
117 | * @return PhpFunctionParameter[] |
||
118 | */ |
||
119 | 160 | protected function getStructMethodParametersValues() |
|
120 | { |
||
121 | 160 | $parametersValues = []; |
|
122 | 160 | foreach ($this->getModelAttributes() as $attribute) { |
|
123 | 160 | $parametersValues[] = $this->getStructMethodParameter($attribute, true); |
|
124 | 64 | } |
|
125 | 160 | return $parametersValues; |
|
126 | } |
||
127 | /** |
||
128 | * @param StructAttributeModel $attribute |
||
129 | * @param bool $lowCaseFirstLetter |
||
130 | * @param mixed $defaultValue |
||
131 | * @return PhpFunctionParameter |
||
132 | */ |
||
133 | 160 | protected function getStructMethodParameter(StructAttributeModel $attribute, $lowCaseFirstLetter = false, $defaultValue = null) |
|
134 | { |
||
135 | try { |
||
136 | 160 | $uniqueString = $attribute->getUniqueString($attribute->getCleanName(), 'method'); |
|
137 | 160 | return new PhpFunctionParameter($lowCaseFirstLetter ? lcfirst($uniqueString) : $uniqueString, isset($defaultValue) ? $defaultValue : $attribute->getDefaultValue(), $this->getStructMethodParameterType($attribute)); |
|
138 | } catch (\InvalidArgumentException $exception) { |
||
139 | throw new \InvalidArgumentException(sprintf('Unable to create function parameter for struct "%s" with type "%s" for attribute "%s"', $this->getModel()->getName(), var_export($this->getStructMethodParameterType($attribute), true), $attribute->getName()), __LINE__, $exception); |
||
140 | } |
||
141 | } |
||
142 | /** |
||
143 | * @param StructAttributeModel $attribute |
||
144 | * @param bool $returnArrayType |
||
145 | * @return string|null |
||
146 | */ |
||
147 | 160 | protected function getStructMethodParameterType(StructAttributeModel $attribute, $returnArrayType = true) |
|
148 | { |
||
149 | 160 | return self::getValidType($this->getStructAttributeTypeHint($attribute, $returnArrayType), null); |
|
150 | } |
||
151 | /** |
||
152 | * @param MethodContainer $methods |
||
153 | * @return Struct |
||
154 | */ |
||
155 | 160 | protected function addStructMethodsSetAndGet(MethodContainer $methods) |
|
156 | { |
||
157 | 160 | foreach ($this->getModelAttributes() as $attribute) { |
|
158 | 160 | $this->addStructMethodGet($methods, $attribute)->addStructMethodSet($methods, $attribute)->addStructMethodAddTo($methods, $attribute); |
|
159 | 64 | } |
|
160 | 160 | return $this; |
|
161 | } |
||
162 | /** |
||
163 | * @param MethodContainer $methods |
||
164 | * @param StructAttributeModel $attribute |
||
165 | * @return Struct |
||
166 | */ |
||
167 | 160 | protected function addStructMethodAddTo(MethodContainer $methods, StructAttributeModel $attribute) |
|
178 | /** |
||
179 | * @param PhpMethod $method |
||
180 | * @param StructAttributeModel $attribute |
||
181 | * @return Struct |
||
182 | */ |
||
183 | 95 | protected function addStructMethodAddToBody(PhpMethod $method, StructAttributeModel $attribute) |
|
184 | { |
||
185 | 95 | if ($this->getGenerator()->getOptionValidation()) { |
|
186 | 95 | $rules = new Rules($this, $method, $attribute); |
|
187 | 95 | $rules->applyRules('item', true); |
|
192 | /** |
||
193 | * @param MethodContainer $methods |
||
194 | * @param StructAttributeModel $attribute |
||
195 | * @return Struct |
||
196 | */ |
||
197 | 160 | protected function addStructMethodSet(MethodContainer $methods, StructAttributeModel $attribute) |
|
206 | /** |
||
207 | * @param PhpMethod $method |
||
208 | * @param StructAttributeModel $attribute |
||
209 | * @return Struct |
||
210 | */ |
||
211 | 160 | protected function addStructMethodSetBody(PhpMethod $method, StructAttributeModel $attribute) |
|
220 | /** |
||
221 | * @param PhpMethod $method |
||
222 | * @param StructAttributeModel $attribute |
||
223 | * @return Struct |
||
224 | */ |
||
225 | 160 | protected function addStructMethodSetBodyAssignment(PhpMethod $method, StructAttributeModel $attribute) |
|
240 | /** |
||
241 | * @param PhpMethod $method |
||
242 | * @return Struct |
||
243 | */ |
||
244 | 160 | protected function addStructMethodSetBodyReturn(PhpMethod $method) |
|
249 | /** |
||
250 | * @param PhpMethod $method |
||
251 | * @param StructAttributeModel $attribute |
||
252 | * @param string $parameterName |
||
253 | * @return Struct |
||
254 | */ |
||
255 | 20 | protected function addStructMethodSetBodyForRestriction(PhpMethod $method, StructAttributeModel $attribute, $parameterName = null) |
|
263 | /** |
||
264 | * @param StructAttributeModel $attribute |
||
265 | * @param string $parameterName |
||
266 | * @return string |
||
267 | */ |
||
268 | 160 | protected function getStructMethodSetBodyAssignment(StructAttributeModel $attribute, $parameterName) |
|
277 | /** |
||
278 | * @param PhpMethod $method |
||
279 | * @param StructAttributeModel $attribute |
||
280 | * @param string $thisAccess |
||
281 | * @return Struct |
||
282 | */ |
||
283 | 160 | protected function addStructMethodGetBody(PhpMethod $method, StructAttributeModel $attribute, $thisAccess) |
|
287 | /** |
||
288 | * @param PhpMethod $method |
||
289 | * @param StructAttributeModel $attribute |
||
290 | * @param string $thisAccess |
||
291 | * @return Struct |
||
292 | */ |
||
293 | 160 | protected function addStructMethodGetBodyForXml(PhpMethod $method, StructAttributeModel $attribute, $thisAccess) |
|
307 | /** |
||
308 | * @param PhpMethod $method |
||
309 | * @param StructAttributeModel $attribute |
||
310 | * @param string $thisAccess |
||
311 | * @return Struct |
||
312 | */ |
||
313 | 160 | protected function addStructMethodGetBodyReturn(PhpMethod $method, StructAttributeModel $attribute, $thisAccess) |
|
328 | /** |
||
329 | * @param MethodContainer $methods |
||
330 | * @param StructAttributeModel $attribute |
||
331 | * @return Struct |
||
332 | */ |
||
333 | 160 | protected function addStructMethodGet(MethodContainer $methods, StructAttributeModel $attribute) |
|
345 | /** |
||
346 | * @param StructAttributeModel $attribute |
||
347 | * @return PhpFunctionParameter[] |
||
348 | */ |
||
349 | 160 | protected function getStructMethodGetParameters(StructAttributeModel $attribute) |
|
357 | /** |
||
358 | * @param MethodContainer $methods |
||
359 | * @return Struct |
||
360 | */ |
||
361 | 160 | protected function addStructMethodSetState(MethodContainer $methods) |
|
370 | /** |
||
371 | * @return PhpAnnotationBlock|null |
||
372 | */ |
||
373 | 160 | protected function getMethodAnnotationBlock(PhpMethod $method) |
|
377 | /** |
||
378 | * @param PhpMethod $method |
||
379 | * @return PhpAnnotationBlock|null |
||
380 | */ |
||
381 | 160 | protected function getStructMethodAnnotationBlock(PhpMethod $method) |
|
401 | /** |
||
402 | * @return PhpAnnotationBlock |
||
403 | */ |
||
404 | 160 | protected function getStructMethodConstructAnnotationBlock() |
|
412 | /** |
||
413 | * @return PhpAnnotationBlock |
||
414 | */ |
||
415 | 160 | protected function getStructMethodSetStateAnnotationBlock() |
|
426 | /** |
||
427 | * @param PhpMethod $method |
||
428 | * @return PhpAnnotationBlock |
||
429 | */ |
||
430 | 160 | protected function getStructMethodsSetAndGetAnnotationBlock(PhpMethod $method) |
|
469 | /** |
||
470 | * @param string $setOrGet |
||
471 | * @param PhpAnnotationBlock $annotationBlock |
||
472 | * @param StructAttributeModel $attribute |
||
473 | * @return Struct |
||
474 | */ |
||
475 | 160 | protected function addStructMethodsSetAndGetAnnotationBlockFromStructAttribute($setOrGet, PhpAnnotationBlock $annotationBlock, StructAttributeModel $attribute) |
|
476 | { |
||
477 | 32 | switch ($setOrGet) { |
|
478 | 160 | case 'set': |
|
479 | 160 | if ($attribute->getRemovableFromRequest()) { |
|
480 | 25 | $annotationBlock->addChild('This property is removable from request (nillable=true+minOccurs=0), therefore if the value assigned to this property is null, it is removed from this object'); |
|
481 | 10 | } |
|
482 | 160 | if (($model = $this->getRestrictionFromStructAttribute($attribute)) instanceof StructModel) { |
|
483 | $annotationBlock |
||
484 | 85 | ->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $model->getPackagedName(true), StructEnum::METHOD_VALUE_IS_VALID))) |
|
485 | 85 | ->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $model->getPackagedName(true), StructEnum::METHOD_GET_VALID_VALUES))) |
|
486 | 85 | ->addChild(new PhpAnnotation(self::ANNOTATION_THROWS, '\InvalidArgumentException')); |
|
487 | 157 | } elseif ($attribute->isArray()) { |
|
488 | 90 | $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_THROWS, '\InvalidArgumentException')); |
|
489 | 36 | } |
|
490 | 160 | $this->addStructMethodsSetAnnotationBlock($annotationBlock, $this->getStructAttributeTypeSetAnnotation($attribute), lcfirst($attribute->getCleanName())); |
|
491 | 160 | break; |
|
492 | 160 | case 'get': |
|
493 | 160 | if ($attribute->getRemovableFromRequest()) { |
|
494 | 25 | $annotationBlock->addChild('An additional test has been added (isset) before returning the property value as this property may have been unset before, due to the fact that this property is removable from the request (nillable=true+minOccurs=0)'); |
|
495 | 10 | } |
|
496 | 160 | $this->addStructMethodsGetAnnotationBlockFromXmlAttribute($annotationBlock, $attribute)->addStructMethodsGetAnnotationBlock($annotationBlock, $this->getStructAttributeTypeGetAnnotation($attribute)); |
|
497 | 160 | break; |
|
498 | } |
||
499 | 160 | return $this; |
|
500 | } |
||
501 | /** |
||
502 | * @param string $setOrGet |
||
503 | * @param PhpAnnotationBlock $annotationBlock |
||
504 | * @param string $attributeName |
||
505 | * @return Struct |
||
506 | */ |
||
507 | 5 | protected function addStructMethodsSetAndGetAnnotationBlockFromScalar($setOrGet, PhpAnnotationBlock $annotationBlock, $attributeName) |
|
508 | { |
||
509 | 1 | switch ($setOrGet) { |
|
510 | 5 | case 'set': |
|
511 | 5 | $this->addStructMethodsSetAnnotationBlock($annotationBlock, lcfirst($attributeName), lcfirst($attributeName)); |
|
512 | 5 | break; |
|
513 | 5 | case 'get': |
|
514 | 5 | $this->addStructMethodsGetAnnotationBlock($annotationBlock, lcfirst($attributeName)); |
|
515 | 5 | break; |
|
516 | } |
||
517 | 5 | return $this; |
|
518 | } |
||
519 | /** |
||
520 | * @param PhpAnnotationBlock $annotationBlock |
||
521 | * @param string $type |
||
522 | * @param string $name |
||
523 | * @return Struct |
||
524 | */ |
||
525 | 160 | protected function addStructMethodsSetAnnotationBlock(PhpAnnotationBlock $annotationBlock, $type, $name) |
|
530 | /** |
||
531 | * @param PhpAnnotationBlock $annotationBlock |
||
532 | * @param string $attributeType |
||
533 | * @return Struct |
||
534 | */ |
||
535 | 160 | protected function addStructMethodsGetAnnotationBlock(PhpAnnotationBlock $annotationBlock, $attributeType) |
|
540 | /** |
||
541 | * @param PhpAnnotationBlock $annotationBlock |
||
542 | * @param StructAttributeModel $attribute |
||
543 | * @return Struct |
||
544 | */ |
||
545 | 160 | protected function addStructMethodsGetAnnotationBlockFromXmlAttribute(PhpAnnotationBlock $annotationBlock, StructAttributeModel $attribute) |
|
558 | /** |
||
559 | * @param PhpAnnotationBlock $annotationBlock |
||
560 | * @return Struct |
||
561 | */ |
||
562 | 160 | protected function addStructPropertiesToAnnotationBlock(PhpAnnotationBlock $annotationBlock) |
|
566 | /** |
||
567 | * @param PhpAnnotationBlock $annotationBlock |
||
568 | * @return Struct |
||
569 | */ |
||
570 | 160 | protected function addStructPropertiesToAnnotationBlockUses(PhpAnnotationBlock $annotationBlock) |
|
577 | /** |
||
578 | * @param PhpAnnotationBlock $annotationBlock |
||
579 | * @return Struct |
||
580 | */ |
||
581 | 160 | protected function addStructPropertiesToAnnotationBlockParams(PhpAnnotationBlock $annotationBlock) |
|
588 | /** |
||
589 | * @param PhpMethod $method |
||
590 | * @return PhpAnnotationBlock |
||
591 | */ |
||
592 | 95 | protected function getStructMethodsAddToAnnotationBlock(PhpMethod $method) |
|
610 | /** |
||
611 | * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getModel() |
||
612 | * @return StructModel |
||
613 | */ |
||
614 | 260 | public function getModel() |
|
618 | /** |
||
619 | * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::setModel() |
||
620 | * @throws \InvalidArgumentException |
||
621 | * @param AbstractModel $model |
||
622 | * @return StructArray |
||
623 | */ |
||
624 | 220 | public function setModel(AbstractModel $model) |
|
631 | } |
||
632 |