Complex classes like TreeGen 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 TreeGen, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
17 | abstract class TreeGen implements TreeGenerable |
||
18 | { |
||
19 | protected $groupBy; |
||
20 | protected $tree; |
||
21 | public $championship; |
||
22 | public $settings; |
||
23 | protected $numFighters; |
||
24 | |||
25 | abstract protected function addFighterToGroup(FightersGroup $group, $fighter); |
||
26 | |||
27 | abstract protected function chunkAndShuffle(Collection $fightersByEntity); |
||
28 | |||
29 | abstract protected function createByeFighter(); |
||
30 | |||
31 | abstract protected function generateAllTrees(); |
||
32 | |||
33 | abstract protected function generateFights(); |
||
34 | |||
35 | abstract protected function generateGroupsForRound(Collection $fightersByArea, $round); |
||
36 | |||
37 | abstract protected function getByeGroup($fighters); |
||
38 | |||
39 | abstract protected function getFighter($fighterId); |
||
40 | |||
41 | abstract protected function getFighters(); |
||
42 | |||
43 | abstract protected function getNumRounds($fightersCount); |
||
44 | |||
45 | abstract protected function syncGroup(FightersGroup $group, $fighters); |
||
46 | |||
47 | /** |
||
48 | * @param Championship $championship |
||
49 | * @param $groupBy |
||
50 | */ |
||
51 | public function __construct(Championship $championship, $groupBy) |
||
58 | |||
59 | /** |
||
60 | * Generate tree groups for a championship. |
||
61 | * |
||
62 | * @throws TreeGenerationException |
||
63 | */ |
||
64 | public function run() |
||
70 | |||
71 | /** |
||
72 | * Generate tree groups for a championship. |
||
73 | * |
||
74 | * @throws TreeGenerationException |
||
75 | */ |
||
76 | public function update(Request $request) |
||
113 | |||
114 | /** |
||
115 | * Get the biggest entity group. |
||
116 | * |
||
117 | * @param $userGroups |
||
118 | * |
||
119 | * @return int |
||
120 | */ |
||
121 | private function getMaxFightersByEntity($userGroups): int |
||
130 | |||
131 | /** |
||
132 | * Get Competitor's list ordered by entities |
||
133 | * Countries for Internation Tournament, State for a National Tournament, etc. |
||
134 | * |
||
135 | * @param $fighters |
||
136 | * |
||
137 | * @return Collection |
||
138 | */ |
||
139 | private function getFightersByEntity($fighters): Collection |
||
150 | |||
151 | /** |
||
152 | * Get the size the first round will have. |
||
153 | * |
||
154 | * @param $fighterCount |
||
155 | * @param $groupSize |
||
156 | * |
||
157 | * @return int |
||
158 | */ |
||
159 | protected function getTreeSize($fighterCount, $groupSize) |
||
181 | |||
182 | /** |
||
183 | * Repart BYE in the tree,. |
||
184 | * |
||
185 | * @param $fighterGroups |
||
186 | * @param int $max |
||
187 | * |
||
188 | * @return Collection |
||
189 | */ |
||
190 | private function repart($fighterGroups, $max) |
||
204 | |||
205 | /** |
||
206 | * Insert byes in an homogen way. |
||
207 | * |
||
208 | * @param Collection $fighters |
||
209 | * @param Collection $byeGroup |
||
210 | * |
||
211 | * @return Collection |
||
212 | */ |
||
213 | private function insertByes(Collection $fighters, Collection $byeGroup) |
||
226 | |||
227 | |||
228 | /** |
||
229 | * @param $order |
||
230 | * @param $round |
||
231 | * @param $parent |
||
232 | * |
||
233 | * @return FightersGroup |
||
234 | */ |
||
235 | protected function saveGroup($order, $round, $parent): FightersGroup |
||
253 | |||
254 | /** |
||
255 | * @param int $groupSize |
||
256 | * |
||
257 | * @return Collection |
||
258 | */ |
||
259 | public function createByeGroup($groupSize): Collection |
||
269 | |||
270 | /** |
||
271 | * @param $fighters |
||
272 | * @param Collection $fighterGroups |
||
273 | * |
||
274 | * @return Collection |
||
275 | */ |
||
276 | public function adjustFightersGroupWithByes($fighters, $fighterGroups): Collection |
||
291 | |||
292 | /** |
||
293 | * Get All Groups on previous round. |
||
294 | * |
||
295 | * @param $currentRound |
||
296 | * |
||
297 | * @return Collection |
||
298 | */ |
||
299 | private function getPreviousRound($currentRound) |
||
305 | |||
306 | /** |
||
307 | * Get the next group on the right ( parent ), final round being the ancestor. |
||
308 | * |
||
309 | * @param $matchNumber |
||
310 | * @param Collection $previousRound |
||
311 | * |
||
312 | * @return mixed |
||
313 | */ |
||
314 | private function getParentGroup($matchNumber, $previousRound) |
||
321 | |||
322 | /** |
||
323 | * Group Fighters by area. |
||
324 | * |
||
325 | * @throws TreeGenerationException |
||
326 | * |
||
327 | * @return Collection |
||
328 | */ |
||
329 | protected function getFightersByArea() |
||
341 | |||
342 | /** |
||
343 | * Attach a parent to every child for nestedSet Navigation. |
||
344 | * |
||
345 | * @param $numFightersElim |
||
346 | */ |
||
347 | protected function addParentToChildren($numFightersElim) |
||
366 | |||
367 | /** |
||
368 | * @param Collection $fighters |
||
369 | * @param $frequency |
||
370 | * @param $sizeGroupBy |
||
371 | * @param $bye |
||
372 | * |
||
373 | * @return Collection |
||
374 | */ |
||
375 | private function getFullFighterList(Collection $fighters, $frequency, $sizeGroupBy, $bye): Collection |
||
391 | |||
392 | /** |
||
393 | * @param $frequency |
||
394 | * @param $sizeGroupBy |
||
395 | * @param $count |
||
396 | * @param $byeCount |
||
397 | * |
||
398 | * @return bool |
||
399 | */ |
||
400 | private function shouldInsertBye($frequency, $sizeGroupBy, $count, $byeCount): bool |
||
404 | |||
405 | /** |
||
406 | * Destroy Previous Fights for demo. |
||
407 | */ |
||
408 | protected function destroyPreviousFights() |
||
414 | |||
415 | /** |
||
416 | * Generate Fights for next rounds. |
||
417 | */ |
||
418 | public function generateNextRoundsFights() |
||
427 | |||
428 | /** |
||
429 | * @param $groupsByRound |
||
430 | */ |
||
431 | protected function updateParentFight($groupsByRound) |
||
444 | |||
445 | /** |
||
446 | * @param $group |
||
447 | * @param $parentFight |
||
448 | */ |
||
449 | protected function chooseAndUpdateParentFight($keyGroup, FightersGroup $group, Fight $parentFight) |
||
466 | |||
467 | /** |
||
468 | * Calculate the area of the group ( group is still not created ). |
||
469 | * |
||
470 | * @param $round |
||
471 | * @param $order |
||
472 | * |
||
473 | * @return int |
||
474 | */ |
||
475 | protected function getNumArea($round, $order) |
||
487 | |||
488 | |||
489 | protected function generateAllFights() |
||
497 | |||
498 | /** |
||
499 | * @param $winners |
||
500 | * @param $numFighter |
||
501 | * @param $fighters |
||
502 | * @return int|null |
||
503 | */ |
||
504 | protected function getWinnerId($winners, $numFighter, $fighters) |
||
511 | |||
512 | /** |
||
513 | * @param $fighters |
||
514 | * @param $numFighter |
||
515 | * @param $fight |
||
516 | * @param $winners |
||
517 | * @return int |
||
518 | */ |
||
519 | protected function updateFight($fighters, $numFighter, $fight, $winners) |
||
534 | } |
||
535 |
It seems like the method you are trying to call exists only in some of the possible types.
Let’s take a look at an example:
Available Fixes
Add an additional type-check:
Only allow a single type to be passed if the variable comes from a parameter: