Complex classes like DescriptorAbstract 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 DescriptorAbstract, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
19 | abstract class DescriptorAbstract implements Filterable |
||
20 | { |
||
21 | /** |
||
22 | * @var string $fqsen Fully Qualified Structural Element Name; the FQCN including method, property of constant name |
||
23 | */ |
||
24 | protected $fqsen = ''; |
||
25 | |||
26 | /** @var string $name The local name for this element */ |
||
27 | protected $name = ''; |
||
28 | |||
29 | /** @var NamespaceDescriptor $namespace The namespace for this element */ |
||
30 | protected $namespace; |
||
31 | |||
32 | /** @var string $package The package with which this element is associated */ |
||
33 | protected $package = ''; |
||
34 | |||
35 | /** @var string $summary A summary describing the function of this element in short. */ |
||
36 | protected $summary = ''; |
||
37 | |||
38 | /** @var string $description A more extensive description of this element. */ |
||
39 | protected $description = ''; |
||
40 | |||
41 | /** @var FileDescriptor|null $file The file to which this element belongs; if applicable */ |
||
42 | protected $fileDescriptor; |
||
43 | |||
44 | /** @var int $line The line number on which this element occurs. */ |
||
45 | protected $line = 0; |
||
46 | |||
47 | /** @var Collection $tags The tags associated with this element. */ |
||
48 | protected $tags; |
||
49 | |||
50 | /** @var Collection $errors A list of errors found while building this element. */ |
||
51 | protected $errors; |
||
52 | |||
53 | /** @var DescriptorAbstract|null the element from which to inherit information in this element */ |
||
54 | protected $inheritedElement = null; |
||
55 | |||
56 | /** |
||
57 | * Initializes this descriptor. |
||
58 | */ |
||
59 | public function __construct() |
||
64 | |||
65 | /** |
||
66 | * Sets the Fully Qualified Structural Element Name (FQSEN) for this element. |
||
67 | * |
||
68 | * @param string $name |
||
69 | * |
||
70 | * @return void |
||
71 | */ |
||
72 | public function setFullyQualifiedStructuralElementName($name) |
||
76 | |||
77 | /** |
||
78 | * Returns the Fully Qualified Structural Element Name (FQSEN) for this element. |
||
79 | * |
||
80 | * @return string |
||
81 | */ |
||
82 | public function getFullyQualifiedStructuralElementName() |
||
86 | |||
87 | /** |
||
88 | * Sets the local name for this element. |
||
89 | * |
||
90 | * @param string $name |
||
91 | * |
||
92 | * @return void |
||
93 | */ |
||
94 | public function setName($name) |
||
98 | |||
99 | /** |
||
100 | * Returns the local name for this element. |
||
101 | * |
||
102 | * @return string |
||
103 | */ |
||
104 | public function getName() |
||
108 | |||
109 | /** |
||
110 | * Sets the namespace (name) for this element. |
||
111 | * |
||
112 | * @param NamespaceDescriptor|string $namespace |
||
113 | */ |
||
114 | public function setNamespace($namespace) |
||
118 | |||
119 | /** |
||
120 | * Returns the namespace for this element or null if none is attached. |
||
121 | * |
||
122 | * @return NamespaceDescriptor|string|null |
||
123 | */ |
||
124 | public function getNamespace() |
||
128 | |||
129 | /** |
||
130 | * Sets the summary describing this element in short. |
||
131 | * |
||
132 | * @param string $summary |
||
133 | * |
||
134 | * @return void |
||
135 | */ |
||
136 | public function setSummary($summary) |
||
140 | |||
141 | /** |
||
142 | * Returns the summary which describes this element. |
||
143 | * |
||
144 | * This method will automatically attempt to inherit the parent's summary if this one has none. |
||
145 | * |
||
146 | * @return string |
||
147 | */ |
||
148 | public function getSummary() |
||
161 | |||
162 | /** |
||
163 | * Sets a description for this element. |
||
164 | * |
||
165 | * @param string $description |
||
166 | * |
||
167 | * @return void |
||
168 | */ |
||
169 | public function setDescription($description) |
||
173 | |||
174 | /** |
||
175 | * Returns the description for this element. |
||
176 | * |
||
177 | * This method will automatically attempt to inherit the parent's description if this one has none. |
||
178 | * |
||
179 | * @return string |
||
180 | */ |
||
181 | public function getDescription() |
||
198 | |||
199 | /** |
||
200 | * Sets the file and linenumber where this element is at. |
||
201 | * |
||
202 | * @param FileDescriptor $file |
||
203 | * @param int $line |
||
204 | * |
||
205 | * @return void |
||
206 | */ |
||
207 | public function setLocation(FileDescriptor $file, $line = 0) |
||
212 | |||
213 | /** |
||
214 | * Returns the path to the file containing this element relative to the project's root. |
||
215 | * |
||
216 | * @return string |
||
217 | */ |
||
218 | public function getPath() |
||
222 | |||
223 | /** |
||
224 | * Returns the file in which this element resides or null in case the element is not bound to a file.. |
||
225 | * |
||
226 | * @return FileDescriptor|null |
||
227 | */ |
||
228 | public function getFile() |
||
232 | |||
233 | /** |
||
234 | * Sets the file to which this element is associated. |
||
235 | * |
||
236 | * @param FileDescriptor $file |
||
237 | * |
||
238 | * @return false |
||
239 | */ |
||
240 | public function setFile(FileDescriptor $file) |
||
244 | |||
245 | /** |
||
246 | * Returns the line number where the definition for this element can be found. |
||
247 | * |
||
248 | * @return int |
||
249 | */ |
||
250 | public function getLine() |
||
254 | |||
255 | /** |
||
256 | * Sets the line number for this element's location in the source file. |
||
257 | * |
||
258 | * @param integer $lineNumber |
||
259 | * |
||
260 | * @return void |
||
261 | */ |
||
262 | public function setLine($lineNumber) |
||
266 | |||
267 | /** |
||
268 | * Sets the tags associated with this element. |
||
269 | * |
||
270 | * @param Collection $tags |
||
271 | * |
||
272 | * @return void |
||
273 | */ |
||
274 | public function setTags(Collection $tags) |
||
278 | |||
279 | /** |
||
280 | * Returns the tags associated with this element. |
||
281 | * |
||
282 | * @return Collection |
||
283 | */ |
||
284 | public function getTags() |
||
288 | |||
289 | /** |
||
290 | * Sets the name of the package to which this element belongs. |
||
291 | * |
||
292 | * @param PackageDescriptor $package |
||
293 | * |
||
294 | * @return void |
||
295 | */ |
||
296 | public function setPackage($package) |
||
300 | |||
301 | /** |
||
302 | * Returns the package name for this element. |
||
303 | * |
||
304 | * @return PackageDescriptor |
||
305 | */ |
||
306 | public function getPackage() |
||
320 | |||
321 | /** |
||
322 | * @return Collection |
||
323 | */ |
||
324 | public function getAuthor() |
||
339 | |||
340 | /** |
||
341 | * Returns the versions for this element. |
||
342 | * |
||
343 | * @return Collection |
||
344 | */ |
||
345 | public function getVersion() |
||
360 | |||
361 | /** |
||
362 | * Returns the copyrights for this element. |
||
363 | * |
||
364 | * @return Collection |
||
365 | */ |
||
366 | public function getCopyright() |
||
381 | |||
382 | /** |
||
383 | * Checks whether this element is deprecated. |
||
384 | * |
||
385 | * @return boolean |
||
386 | */ |
||
387 | public function isDeprecated() |
||
391 | |||
392 | /** |
||
393 | * Sets a list of all errors associated with this element. |
||
394 | * |
||
395 | * @param Collection $errors |
||
396 | */ |
||
397 | public function setErrors(Collection $errors) |
||
401 | |||
402 | /** |
||
403 | * Returns all errors that occur in this element. |
||
404 | * |
||
405 | * @return Collection |
||
406 | */ |
||
407 | public function getErrors() |
||
411 | |||
412 | /** |
||
413 | * Dynamically constructs a set of getters to retrieve tag (collections) with. |
||
414 | * |
||
415 | * Important: __call() is not a fast method of access; it is preferred to directly use the getTags() collection. |
||
416 | * This interface is provided to allow for uniform and easy access to certain tags. |
||
417 | * |
||
418 | * @param string $name |
||
419 | * @param mixed[] $arguments |
||
420 | * |
||
421 | * @return Collection|null |
||
422 | */ |
||
423 | public function __call($name, $arguments) |
||
434 | |||
435 | /** |
||
436 | * Represents this object by its unique identifier, the Fully Qualified Structural Element Name. |
||
437 | * |
||
438 | * @return string |
||
439 | */ |
||
440 | public function __toString() |
||
444 | |||
445 | /** |
||
446 | * @return DescriptorAbstract|null |
||
447 | */ |
||
448 | public function getInheritedElement() |
||
452 | } |
||
453 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.