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 |
|
310 | 4 | ||
311 | 1 | /** |
|
312 | * @param PlayerContract $player |
||
313 | */ |
||
314 | 3 | public function postSmallBlind(PlayerContract $player) |
|
324 | |||
325 | 34 | /** |
|
326 | * @param PlayerContract $player |
||
327 | 34 | */ |
|
328 | 34 | public function postBigBlind(PlayerContract $player) |
|
338 | |||
339 | 34 | /** |
|
340 | * @return Chips |
||
341 | 34 | */ |
|
342 | 34 | private function smallBlind(): Chips |
|
346 | |||
347 | /** |
||
348 | 34 | * @return Chips |
|
349 | */ |
||
350 | 34 | private function bigBlind(): Chips |
|
354 | |||
355 | /** |
||
356 | 34 | * @return ChipPot |
|
357 | */ |
||
358 | 34 | public function currentPot(): ChipPot |
|
362 | |||
363 | /** |
||
364 | 14 | * @return ChipPotCollection |
|
365 | */ |
||
366 | 14 | public function chipPots(): ChipPotCollection |
|
370 | |||
371 | /** |
||
372 | 20 | * @param PlayerContract $player |
|
373 | * |
||
374 | 20 | * @return Chips |
|
375 | */ |
||
376 | public function playerBetStack(PlayerContract $player): Chips |
||
380 | |||
381 | /** |
||
382 | 31 | * @param PlayerContract $player |
|
383 | * @param Chips $chips |
||
384 | 31 | */ |
|
385 | private function postBlind(PlayerContract $player, $chips) |
||
392 | |||
393 | 34 | /** |
|
394 | * @return PlayerContract|false |
||
395 | */ |
||
396 | 34 | public function whosTurnIsIt() |
|
410 | |||
411 | /** |
||
412 | 1 | * @return ChipPotCollection |
|
413 | */ |
||
414 | public function collectChipTotal(): ChipPotCollection |
||
494 | |||
495 | 5 | /** |
|
496 | * Deal the Flop. |
||
497 | 5 | */ |
|
498 | 5 | public function dealFlop() |
|
517 | 17 | ||
518 | 1 | /** |
|
519 | * Deal the turn card. |
||
520 | 17 | */ |
|
521 | 1 | public function dealTurn() |
|
540 | |||
541 | /** |
||
542 | * Deal the river card. |
||
543 | */ |
||
544 | 14 | public function dealRiver() |
|
563 | |||
564 | 10 | /** |
|
565 | 1 | * @throws RoundException |
|
566 | */ |
||
567 | public function checkPlayerTryingToAct(PlayerContract $player) |
||
577 | |||
578 | 12 | /** |
|
579 | 12 | * @param PlayerContract $player |
|
580 | 12 | * |
|
581 | 12 | * @throws RoundException |
|
582 | 12 | */ |
|
583 | public function playerCalls(PlayerContract $player) |
||
607 | |||
608 | /** |
||
609 | * @param PlayerContract $player |
||
610 | 22 | * @param Chips $chips |
|
611 | * |
||
612 | 22 | * @throws RoundException |
|
613 | */ |
||
614 | 22 | public function playerRaises(PlayerContract $player, Chips $chips) |
|
633 | 4 | ||
634 | /** |
||
635 | 4 | * @param PlayerContract $player |
|
636 | * |
||
637 | 4 | * @throws RoundException |
|
638 | 3 | */ |
|
639 | 3 | public function playerFoldsHand(PlayerContract $player) |
|
648 | 14 | ||
649 | /** |
||
650 | 13 | * @param PlayerContract $player |
|
651 | * |
||
652 | 13 | * @throws RoundException |
|
653 | 13 | */ |
|
654 | 13 | public function playerPushesAllIn(PlayerContract $player) |
|
667 | |||
668 | /** |
||
669 | 14 | * @param PlayerContract $player |
|
670 | * |
||
671 | 14 | * @throws RoundException |
|
672 | 14 | */ |
|
673 | 14 | public function playerChecks(PlayerContract $player) |
|
684 | 15 | ||
685 | 15 | /** |
|
686 | 15 | * @return Chips |
|
687 | */ |
||
688 | private function highestBet(): Chips |
||
694 | 22 | ||
695 | 22 | /** |
|
696 | * @param PlayerContract $player |
||
697 | * @param Chips $chips |
||
698 | */ |
||
699 | private function placeChipBet(PlayerContract $player, Chips $chips) |
||
711 | |||
712 | 30 | /** |
|
713 | 30 | * Reset the chip stack for all players. |
|
714 | */ |
||
715 | private function resetBetStacks() |
||
721 | 50 | ||
722 | 50 | /** |
|
723 | 50 | * Reset the leftToAct collection. |
|
724 | */ |
||
725 | private function setupLeftToAct() |
||
737 | 46 | ||
738 | 46 | /** |
|
739 | 46 | * @param PlayerContract $player |
|
740 | */ |
||
741 | public function sitPlayerOut(PlayerContract $player) |
||
746 | 1 | ||
747 | 1 | /** |
|
748 | 1 | * @var int |
|
749 | */ |
||
750 | public function resetPlayerList(int $seat) |
||
757 | } |
||
758 |
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: