Complex classes like Round 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 Round, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
16 | class Round |
||
17 | { |
||
18 | /** |
||
19 | * @var Uuid |
||
20 | */ |
||
21 | private $id; |
||
22 | |||
23 | /** |
||
24 | * @var Table |
||
25 | */ |
||
26 | private $table; |
||
27 | |||
28 | /** |
||
29 | * @var ChipStackCollection |
||
30 | */ |
||
31 | private $betStacks; |
||
32 | |||
33 | /** |
||
34 | * @var PlayerCollection |
||
35 | */ |
||
36 | private $foldedPlayers; |
||
37 | |||
38 | /** |
||
39 | * @var ChipPotCollection |
||
40 | */ |
||
41 | private $chipPots; |
||
42 | |||
43 | /** |
||
44 | * @var ChipPot |
||
45 | */ |
||
46 | private $currentPot; |
||
47 | |||
48 | /** |
||
49 | * @var ActionCollection |
||
50 | */ |
||
51 | private $actions; |
||
52 | |||
53 | /** |
||
54 | * @var PlayerCollection |
||
55 | */ |
||
56 | private $leftToAct; |
||
57 | |||
58 | /** |
||
59 | * @var GameParameters |
||
60 | */ |
||
61 | private $gameRules; |
||
62 | |||
63 | /** |
||
64 | * Round constructor. |
||
65 | * |
||
66 | * @param Uuid $id |
||
67 | * @param Table $table |
||
68 | * @param GameParameters $gameRules |
||
69 | */ |
||
70 | private function __construct(Uuid $id, Table $table, GameParameters $gameRules) |
||
92 | |||
93 | /** |
||
94 | 50 | * Start a Round of poker. |
|
95 | * |
||
96 | * @param Uuid $id |
||
97 | 50 | * @param Table $table |
|
98 | 50 | * @param GameParameters $gameRules |
|
99 | 50 | * |
|
100 | * @return Round |
||
101 | */ |
||
102 | public static function start(Uuid $id, Table $table, GameParameters $gameRules): Round |
||
106 | |||
107 | /** |
||
108 | 50 | * Run the cleanup procedure for an end of Round. |
|
109 | */ |
||
110 | 50 | public function end() |
|
120 | 11 | ||
121 | /** |
||
122 | 11 | * @return Uuid |
|
123 | */ |
||
124 | 11 | public function id(): Uuid |
|
128 | |||
129 | /** |
||
130 | 50 | * @return DealerContract |
|
131 | */ |
||
132 | 50 | public function dealer(): DealerContract |
|
136 | |||
137 | /** |
||
138 | 3 | * @return PlayerCollection |
|
139 | */ |
||
140 | 3 | public function players(): PlayerCollection |
|
144 | |||
145 | /** |
||
146 | 12 | * @return PlayerCollection |
|
147 | */ |
||
148 | 12 | public function playersStillIn(): PlayerCollection |
|
152 | |||
153 | /** |
||
154 | 19 | * @return PlayerCollection |
|
155 | */ |
||
156 | 19 | public function foldedPlayers(): PlayerCollection |
|
160 | |||
161 | /** |
||
162 | 1 | * @return ActionCollection |
|
163 | */ |
||
164 | 1 | public function actions(): ActionCollection |
|
165 | { |
||
166 | return $this->actions; |
||
167 | } |
||
168 | |||
169 | /** |
||
170 | 35 | * @return LeftToAct |
|
171 | */ |
||
172 | 35 | public function leftToAct(): LeftToAct |
|
176 | |||
177 | /** |
||
178 | 36 | * @return Table |
|
179 | */ |
||
180 | 36 | public function table(): Table |
|
184 | |||
185 | /** |
||
186 | 50 | * @return ChipStackCollection |
|
187 | */ |
||
188 | 50 | public function betStacks(): ChipStackCollection |
|
192 | |||
193 | /** |
||
194 | 13 | * @return GameParameters |
|
195 | */ |
||
196 | 13 | public function gameRules(): GameParameters |
|
200 | |||
201 | /** |
||
202 | 29 | * @return int |
|
203 | */ |
||
204 | 29 | public function betStacksTotal(): int |
|
208 | |||
209 | public function dealHands() |
||
217 | |||
218 | 2 | /** |
|
219 | * Runs over each chipPot and assigns the chips to the winning player. |
||
220 | 2 | */ |
|
221 | private function distributeWinnings() |
||
266 | |||
267 | 1 | /** |
|
268 | * @param Player $actualPlayer |
||
269 | 11 | * |
|
270 | * @return bool |
||
271 | 11 | */ |
|
272 | public function playerIsStillIn(PlayerContract $actualPlayer) |
||
278 | 1 | ||
279 | /** |
||
280 | 1 | * @return PlayerContract |
|
281 | */ |
||
282 | 1 | public function playerWithButton(): PlayerContract |
|
286 | |||
287 | /** |
||
288 | 7 | * @return PlayerContract |
|
289 | */ |
||
290 | 7 | public function playerWithSmallBlind(): PlayerContract |
|
298 | 21 | ||
299 | 5 | /** |
|
300 | * @return PlayerContract |
||
301 | */ |
||
302 | 16 | public function playerWithBigBlind(): PlayerContract |
|
312 | |||
313 | /** |
||
314 | 3 | * @param PlayerContract $player |
|
315 | */ |
||
316 | public function postSmallBlind(PlayerContract $player) |
||
326 | |||
327 | 34 | /** |
|
328 | 34 | * @param PlayerContract $player |
|
329 | 34 | */ |
|
330 | public function postBigBlind(PlayerContract $player) |
||
340 | |||
341 | 34 | /** |
|
342 | 34 | * @return Chips |
|
343 | 34 | */ |
|
344 | private function smallBlind(): Chips |
||
348 | 34 | ||
349 | /** |
||
350 | 34 | * @return Chips |
|
351 | */ |
||
352 | private function bigBlind(): Chips |
||
356 | 34 | ||
357 | /** |
||
358 | 34 | * @return ChipPot |
|
359 | */ |
||
360 | public function currentPot(): ChipPot |
||
364 | 14 | ||
365 | /** |
||
366 | 14 | * @return ChipPotCollection |
|
367 | */ |
||
368 | public function chipPots(): ChipPotCollection |
||
372 | 20 | ||
373 | /** |
||
374 | 20 | * @param PlayerContract $player |
|
375 | * |
||
376 | * @return Chips |
||
377 | */ |
||
378 | public function playerBetStack(PlayerContract $player): Chips |
||
382 | 31 | ||
383 | /** |
||
384 | 31 | * @param PlayerContract $player |
|
385 | * @param Chips $chips |
||
386 | */ |
||
387 | private function postBlind(PlayerContract $player, $chips) |
||
394 | |||
395 | /** |
||
396 | 34 | * @return PlayerContract|false |
|
397 | 34 | */ |
|
398 | public function whosTurnIsIt() |
||
412 | 1 | ||
413 | /** |
||
414 | * @return ChipPotCollection |
||
415 | */ |
||
416 | public function collectChipTotal(): ChipPotCollection |
||
496 | |||
497 | 5 | /** |
|
498 | 5 | * Deal the Flop. |
|
499 | 5 | */ |
|
500 | 6 | public function dealFlop() |
|
519 | |||
520 | 17 | /** |
|
521 | 1 | * Deal the turn card. |
|
522 | */ |
||
523 | public function dealTurn() |
||
542 | |||
543 | /** |
||
544 | 14 | * Deal the river card. |
|
545 | */ |
||
546 | 14 | public function dealRiver() |
|
565 | 1 | ||
566 | /** |
||
567 | * @throws RoundException |
||
568 | 9 | */ |
|
569 | 9 | public function checkPlayerTryingToAct(PlayerContract $player) |
|
579 | 12 | ||
580 | 12 | /** |
|
581 | 12 | * @param PlayerContract $player |
|
582 | 12 | * |
|
583 | * @throws RoundException |
||
584 | */ |
||
585 | 12 | public function playerCalls(PlayerContract $player) |
|
609 | |||
610 | 22 | /** |
|
611 | * @param PlayerContract $player |
||
612 | 22 | * @param Chips $chips |
|
613 | * |
||
614 | 22 | * @throws RoundException |
|
615 | */ |
||
616 | public function playerRaises(PlayerContract $player, Chips $chips) |
||
638 | 3 | ||
639 | 3 | /** |
|
640 | * @param PlayerContract $player |
||
641 | * |
||
642 | * @throws RoundException |
||
643 | */ |
||
644 | public function playerFoldsHand(PlayerContract $player) |
||
653 | 13 | ||
654 | 13 | /** |
|
655 | * @param PlayerContract $player |
||
656 | * |
||
657 | * @throws RoundException |
||
658 | */ |
||
659 | public function playerPushesAllIn(PlayerContract $player) |
||
672 | 14 | ||
673 | 14 | /** |
|
674 | * @param PlayerContract $player |
||
675 | * |
||
676 | * @throws RoundException |
||
677 | */ |
||
678 | public function playerChecks(PlayerContract $player) |
||
689 | |||
690 | /** |
||
691 | 22 | * @return Chips |
|
692 | */ |
||
693 | private function highestBet(): Chips |
||
699 | |||
700 | /** |
||
701 | * @param PlayerContract $player |
||
702 | 30 | * @param Chips $chips |
|
703 | */ |
||
704 | 30 | private function placeChipBet(PlayerContract $player, Chips $chips) |
|
716 | |||
717 | /** |
||
718 | * Reset the chip stack for all players. |
||
719 | */ |
||
720 | 50 | private function resetBetStacks() |
|
726 | |||
727 | /** |
||
728 | 50 | * Reset the leftToAct collection. |
|
729 | */ |
||
730 | 50 | private function setupLeftToAct() |
|
742 | |||
743 | /** |
||
744 | 1 | * @param PlayerContract $player |
|
745 | */ |
||
746 | 1 | public function sitPlayerOut(PlayerContract $player) |
|
751 | |||
752 | /** |
||
753 | * @var int |
||
754 | */ |
||
755 | public function resetPlayerList(int $seat) |
||
762 | } |
||
763 |
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the interface: