Complex classes like InnerNode 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 InnerNode, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 13 | abstract class InnerNode extends ArrayNode |
||
| 14 | { |
||
| 15 | |||
| 16 | /** |
||
| 17 | * An array of all the children. |
||
| 18 | * |
||
| 19 | * @var array |
||
| 20 | */ |
||
| 21 | protected $children = []; |
||
| 22 | |||
| 23 | /** |
||
| 24 | * Sets the encoding class to this node and propagates it |
||
| 25 | * to all its children. |
||
| 26 | * |
||
| 27 | * @param Encode $encode |
||
| 28 | * @return void |
||
| 29 | */ |
||
| 30 | public function propagateEncoding(Encode $encode) |
||
| 41 | |||
| 42 | /** |
||
| 43 | * Checks if this node has children. |
||
| 44 | * |
||
| 45 | * @return bool |
||
| 46 | */ |
||
| 47 | public function hasChildren() |
||
| 51 | |||
| 52 | /** |
||
| 53 | * Returns the child by id. |
||
| 54 | * |
||
| 55 | * @param int $id |
||
| 56 | * @return AbstractNode |
||
| 57 | * @throws ChildNotFoundException |
||
| 58 | */ |
||
| 59 | public function getChild($id) |
||
| 67 | |||
| 68 | /** |
||
| 69 | * Returns a new array of child nodes |
||
| 70 | * |
||
| 71 | * @return array |
||
| 72 | */ |
||
| 73 | public function getChildren() |
||
| 88 | |||
| 89 | /** |
||
| 90 | * Counts children |
||
| 91 | * |
||
| 92 | * @return int |
||
| 93 | */ |
||
| 94 | public function countChildren() |
||
| 98 | |||
| 99 | /** |
||
| 100 | * Adds a child node to this node and returns the id of the child for this |
||
| 101 | * parent. |
||
| 102 | * |
||
| 103 | * @param AbstractNode $child |
||
| 104 | * @return bool |
||
| 105 | * @throws CircularException |
||
| 106 | */ |
||
| 107 | public function addChild(AbstractNode $child, $before = null) |
||
| 175 | |||
| 176 | /** |
||
| 177 | * Insert element before child with provided id |
||
| 178 | * |
||
| 179 | * @param AbstractNode $child |
||
| 180 | * @return bool |
||
| 181 | * @param int $id |
||
| 182 | */ |
||
| 183 | public function insertBefore(AbstractNode $child, $id){ |
||
| 186 | |||
| 187 | /** |
||
| 188 | * Insert element before after with provided id |
||
| 189 | * |
||
| 190 | * @param AbstractNode $child |
||
| 191 | * @return bool |
||
| 192 | * @param int $id |
||
| 193 | */ |
||
| 194 | public function insertAfter(AbstractNode $child, $id){ |
||
| 205 | |||
| 206 | /** |
||
| 207 | * Removes the child by id. |
||
| 208 | * |
||
| 209 | * @param int $id |
||
| 210 | * @return $this |
||
| 211 | */ |
||
| 212 | public function removeChild($id) |
||
| 236 | |||
| 237 | /** |
||
| 238 | * Attempts to get the next child. |
||
| 239 | * |
||
| 240 | * @param int $id |
||
| 241 | * @return AbstractNode |
||
| 242 | * @uses $this->getChild() |
||
| 243 | * @throws ChildNotFoundException |
||
| 244 | */ |
||
| 245 | public function nextChild($id) |
||
| 252 | |||
| 253 | /** |
||
| 254 | * Attempts to get the previous child. |
||
| 255 | * |
||
| 256 | * @param int $id |
||
| 257 | * @return AbstractNode |
||
| 258 | * @uses $this->getChild() |
||
| 259 | * @throws ChildNotFoundException |
||
| 260 | */ |
||
| 261 | public function previousChild($id) |
||
| 268 | |||
| 269 | /** |
||
| 270 | * Checks if the given node id is a child of the |
||
| 271 | * current node. |
||
| 272 | * |
||
| 273 | * @param int $id |
||
| 274 | * @return bool |
||
| 275 | */ |
||
| 276 | public function isChild($id) |
||
| 286 | |||
| 287 | /** |
||
| 288 | * Removes the child with id $childId and replace it with the new child |
||
| 289 | * $newChild. |
||
| 290 | * |
||
| 291 | * @param int $childId |
||
| 292 | * @param AbstractNode $newChild |
||
| 293 | * @throws ChildNotFoundException |
||
| 294 | */ |
||
| 295 | public function replaceChild($childId, AbstractNode $newChild) |
||
| 305 | |||
| 306 | /** |
||
| 307 | * Shortcut to return the first child. |
||
| 308 | * |
||
| 309 | * @return AbstractNode |
||
| 310 | * @uses $this->getChild() |
||
| 311 | */ |
||
| 312 | public function firstChild() |
||
| 319 | |||
| 320 | /** |
||
| 321 | * Attempts to get the last child. |
||
| 322 | * |
||
| 323 | * @return AbstractNode |
||
| 324 | */ |
||
| 325 | public function lastChild() |
||
| 332 | |||
| 333 | /** |
||
| 334 | * Checks if the given node id is a descendant of the |
||
| 335 | * current node. |
||
| 336 | * |
||
| 337 | * @param int $id |
||
| 338 | * @return bool |
||
| 339 | */ |
||
| 340 | public function isDescendant($id) |
||
| 359 | |||
| 360 | /** |
||
| 361 | * Sets the parent node. |
||
| 362 | * |
||
| 363 | * @param InnerNode $parent |
||
| 364 | * @return $this |
||
| 365 | * @throws CircularException |
||
| 366 | */ |
||
| 367 | public function setParent(InnerNode $parent) |
||
| 376 | } |