Total Complexity | 55 |
Total Lines | 436 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like ADefaults 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.
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 ADefaults, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
23 | abstract class ADefaults implements IDefaults |
||
24 | { |
||
25 | use DefaultConst; |
||
26 | |||
27 | protected static int $millisecondsInterval; |
||
28 | protected static float|int $shutdownDelay; |
||
29 | protected static float|int $shutdownMaxDelay; |
||
30 | protected static bool $isModeSynchronous; |
||
31 | protected static bool $hideCursor; |
||
32 | protected static string $messageOnFinalize; |
||
33 | protected static string $messageOnExit; |
||
34 | protected static string $messageOnInterrupt; |
||
35 | protected static string $percentNumberFormat; |
||
36 | protected static bool $createInitialized; |
||
37 | protected static array $colorSupportLevels; |
||
38 | protected static ?array $defaultStylePattern = null; |
||
39 | protected static ?array $defaultCharPattern = null; |
||
40 | protected static ?array $mainStylePattern = null; |
||
41 | protected static ?array $mainCharPattern = null; |
||
42 | protected static ?IFrame $mainLeadingSpacer = null; |
||
43 | protected static ?IFrame $mainTrailingSpacer = null; |
||
44 | protected static ?IFrame $defaultLeadingSpacer = null; |
||
45 | protected static ?IFrame $defaultTrailingSpacer = null; |
||
46 | protected static IClasses $classes; |
||
47 | protected static ITerminal $terminal; |
||
48 | protected static bool $autoStart; |
||
49 | protected static bool $attachSignalHandlers; |
||
50 | /** |
||
51 | * @var resource |
||
52 | */ |
||
53 | protected static $outputStream; |
||
54 | protected static iterable $loopProbes; |
||
55 | protected static iterable $terminalProbes; |
||
56 | private static ?IDefaults $instance = null; // private, singleton |
||
57 | |||
58 | |||
59 | private function __construct() |
||
60 | { |
||
61 | $this->reset(); |
||
62 | } |
||
63 | |||
64 | public function reset(): void |
||
65 | { |
||
66 | self::$outputStream = self::defaultOutputStream(); |
||
67 | self::$loopProbes = self::defaultLoopProbes(); |
||
68 | self::$terminalProbes = self::defaultTerminalProbes(); |
||
69 | self::$classes = self::getClassesInstance(); |
||
70 | self::$terminal = self::getTerminalInstance(); |
||
71 | |||
72 | self::$shutdownDelay = self::SHUTDOWN_DELAY; |
||
73 | self::$shutdownMaxDelay = self::SHUTDOWN_MAX_DELAY; |
||
74 | self::$messageOnFinalize = self::MESSAGE_ON_FINALIZE; |
||
75 | self::$messageOnExit = self::MESSAGE_ON_EXIT; |
||
76 | self::$messageOnInterrupt = self::MESSAGE_ON_INTERRUPT; |
||
77 | self::$hideCursor = self::TERMINAL_HIDE_CURSOR; |
||
78 | self::$colorSupportLevels = self::TERMINAL_COLOR_SUPPORT_LEVELS; |
||
79 | self::$isModeSynchronous = self::SPINNER_MODE_IS_SYNCHRONOUS; |
||
80 | self::$createInitialized = self::SPINNER_CREATE_INITIALIZED; |
||
81 | self::$percentNumberFormat = self::PERCENT_NUMBER_FORMAT; |
||
82 | self::$millisecondsInterval = self::INTERVAL_MS; |
||
83 | self::$autoStart = self::AUTO_START; |
||
84 | self::$attachSignalHandlers = self::ATTACH_SIGNAL_HANDLERS; |
||
85 | |||
86 | self::$mainStylePattern = null; |
||
87 | self::$mainCharPattern = null; |
||
88 | self::$mainLeadingSpacer = null; |
||
89 | self::$mainTrailingSpacer = null; |
||
90 | |||
91 | self::$defaultStylePattern = []; |
||
92 | self::$defaultCharPattern = []; |
||
93 | self::$defaultLeadingSpacer = Frame::createEmpty(); |
||
94 | self::$defaultTrailingSpacer = Frame::createSpace(); |
||
95 | } |
||
96 | |||
97 | /** |
||
98 | * @return resource |
||
99 | */ |
||
100 | protected static function defaultOutputStream() |
||
101 | { |
||
102 | return STDERR; |
||
103 | } |
||
104 | |||
105 | protected static function defaultLoopProbes(): iterable |
||
106 | { |
||
107 | // @codeCoverageIgnoreStart |
||
108 | yield from [ |
||
109 | RevoltLoopProbe::class, |
||
110 | ReactLoopProbe::class, |
||
111 | ]; |
||
112 | // @codeCoverageIgnoreEnd |
||
113 | } |
||
114 | |||
115 | protected static function defaultTerminalProbes(): iterable |
||
116 | { |
||
117 | // @codeCoverageIgnoreStart |
||
118 | yield from [ |
||
119 | SymfonyTerminalProbe::class, |
||
120 | ]; |
||
121 | // @codeCoverageIgnoreEnd |
||
122 | } |
||
123 | |||
124 | protected static function getClassesInstance(): AClasses |
||
125 | { |
||
126 | return AClasses::getInstance(); |
||
127 | } |
||
128 | |||
129 | final public static function getInstance(): self |
||
130 | { |
||
131 | if (null === self::$instance) { |
||
132 | self::$instance = |
||
133 | new class() extends ADefaults { |
||
134 | }; |
||
135 | } |
||
136 | return self::$instance; |
||
137 | } |
||
138 | |||
139 | protected static function getTerminalInstance(): ITerminal |
||
140 | { |
||
141 | return ATerminal::getInstance(self::$terminalProbes); |
||
142 | } |
||
143 | |||
144 | public function getClasses(): IClasses |
||
145 | { |
||
146 | return self::$classes; |
||
147 | } |
||
148 | |||
149 | /** @inheritdoc */ |
||
150 | public function getOutputStream() |
||
151 | { |
||
152 | return self::$outputStream; |
||
153 | } |
||
154 | |||
155 | /** @inheritdoc */ |
||
156 | public function setOutputStream($stream): static |
||
157 | { |
||
158 | Asserter::assertStream($stream); |
||
159 | self::$outputStream = $stream; |
||
160 | return $this; |
||
161 | } |
||
162 | |||
163 | public function getIntervalMilliseconds(): int |
||
164 | { |
||
165 | return self::$millisecondsInterval; |
||
166 | } |
||
167 | |||
168 | public function setIntervalMilliseconds(int $defaultInterval): static |
||
169 | { |
||
170 | self::$millisecondsInterval = $defaultInterval; |
||
171 | return $this; |
||
172 | } |
||
173 | |||
174 | public function getShutdownDelay(): float|int |
||
175 | { |
||
176 | return self::$shutdownDelay; |
||
177 | } |
||
178 | |||
179 | public function setShutdownDelay(float|int $shutdownDelay): static |
||
180 | { |
||
181 | self::$shutdownDelay = $shutdownDelay; |
||
182 | return $this; |
||
183 | } |
||
184 | |||
185 | public function isModeSynchronous(): bool |
||
186 | { |
||
187 | return self::$isModeSynchronous; |
||
188 | } |
||
189 | |||
190 | public function setModeAsSynchronous(bool $isModeSynchronous): static |
||
191 | { |
||
192 | self::$isModeSynchronous = $isModeSynchronous; |
||
193 | return $this; |
||
194 | } |
||
195 | |||
196 | public function isHideCursor(): bool |
||
197 | { |
||
198 | return self::$hideCursor; |
||
199 | } |
||
200 | |||
201 | public function setHideCursor(bool $hideCursor): static |
||
202 | { |
||
203 | self::$hideCursor = $hideCursor; |
||
204 | return $this; |
||
205 | } |
||
206 | |||
207 | public function getDefaultCharPattern(): array |
||
208 | { |
||
209 | return self::$defaultCharPattern; |
||
210 | } |
||
211 | |||
212 | public function setDefaultCharPattern(array $char): static |
||
213 | { |
||
214 | self::$defaultCharPattern = $char; |
||
215 | return $this; |
||
216 | } |
||
217 | |||
218 | public function getDefaultStylePattern(): array |
||
219 | { |
||
220 | return self::$defaultStylePattern; |
||
221 | } |
||
222 | |||
223 | public function setDefaultStylePattern(array $style): static |
||
224 | { |
||
225 | self::$defaultStylePattern = $style; |
||
226 | return $this; |
||
227 | } |
||
228 | |||
229 | public function getFinalMessage(): string |
||
230 | { |
||
231 | return self::$messageOnFinalize; |
||
232 | } |
||
233 | |||
234 | public function setFinalMessage(string $finalMessage): static |
||
235 | { |
||
236 | self::$messageOnFinalize = $finalMessage; |
||
237 | return $this; |
||
238 | } |
||
239 | |||
240 | public function getMessageOnExit(): string |
||
241 | { |
||
242 | return self::$messageOnExit; |
||
243 | } |
||
244 | |||
245 | public function setMessageOnExit(string $messageOnExit): static |
||
246 | { |
||
247 | self::$messageOnExit = $messageOnExit; |
||
248 | return $this; |
||
249 | } |
||
250 | |||
251 | public function getInterruptMessage(): string |
||
252 | { |
||
253 | return self::$messageOnInterrupt; |
||
254 | } |
||
255 | |||
256 | public function setInterruptMessage(string $interruptMessage): static |
||
257 | { |
||
258 | self::$messageOnInterrupt = $interruptMessage; |
||
259 | return $this; |
||
260 | } |
||
261 | |||
262 | public function getMaxShutdownDelay(): float|int |
||
263 | { |
||
264 | return self::$shutdownMaxDelay; |
||
265 | } |
||
266 | |||
267 | public function setMaxShutdownDelay(float|int $maxShutdownDelay): static |
||
268 | { |
||
269 | self::$shutdownMaxDelay = $maxShutdownDelay; |
||
270 | return $this; |
||
271 | } |
||
272 | |||
273 | public function getColorSupportLevels(): array |
||
274 | { |
||
275 | return self::$colorSupportLevels; |
||
276 | } |
||
277 | |||
278 | /** @inheritdoc */ |
||
279 | public function setColorSupportLevels(array $colorSupportLevels): static |
||
280 | { |
||
281 | Asserter::assertColorSupportLevels($colorSupportLevels); |
||
282 | self::$colorSupportLevels = $colorSupportLevels; |
||
283 | return $this; |
||
284 | } |
||
285 | |||
286 | |||
287 | public function getPercentNumberFormat(): string |
||
288 | { |
||
289 | return self::$percentNumberFormat; |
||
290 | } |
||
291 | |||
292 | public function setPercentNumberFormat(string $percentNumberFormat): static |
||
293 | { |
||
294 | self::$percentNumberFormat = $percentNumberFormat; |
||
295 | return $this; |
||
296 | } |
||
297 | |||
298 | public function getSpinnerStylePattern(): array |
||
336 | } |
||
337 | |||
338 | public function setSpinnerStylePattern(array $spinnerStylePattern): static |
||
339 | { |
||
340 | self::$mainStylePattern = $spinnerStylePattern; |
||
341 | return $this; |
||
342 | } |
||
343 | |||
344 | public function getSpinnerCharPattern(): array |
||
345 | { |
||
346 | // TODO (2022-10-14 16:03) [Alec Rabbit]: change return type to ? [f96f5d87-f9f9-46dc-a45b-8eecc2aba711] |
||
347 | if (null === self::$mainCharPattern) { |
||
348 | self::$mainCharPattern = ['⠏', '⠛', '⠹', '⢸', '⣰', '⣤', '⣆', '⡇']; |
||
349 | } |
||
350 | return self::$mainCharPattern; |
||
351 | } |
||
352 | |||
353 | public function setSpinnerCharPattern(array $spinnerCharPattern): static |
||
354 | { |
||
355 | self::$mainCharPattern = $spinnerCharPattern; |
||
356 | return $this; |
||
357 | } |
||
358 | |||
359 | public function getMainLeadingSpacer(): IFrame |
||
360 | { |
||
361 | return |
||
362 | self::$mainLeadingSpacer ?? self::$defaultLeadingSpacer; |
||
363 | } |
||
364 | |||
365 | public function setMainLeadingSpacer(IFrame $mainLeadingSpacer): static |
||
366 | { |
||
367 | self::$mainLeadingSpacer = $mainLeadingSpacer; |
||
368 | return $this; |
||
369 | } |
||
370 | |||
371 | public function getMainTrailingSpacer(): IFrame |
||
372 | { |
||
373 | return |
||
374 | self::$mainTrailingSpacer ?? self::$defaultTrailingSpacer; |
||
375 | } |
||
376 | |||
377 | public function setMainTrailingSpacer(IFrame $mainTrailingSpacer): static |
||
378 | { |
||
379 | self::$mainTrailingSpacer = $mainTrailingSpacer; |
||
380 | return $this; |
||
381 | } |
||
382 | |||
383 | public function isCreateInitialized(): bool |
||
384 | { |
||
385 | return self::$createInitialized; |
||
386 | } |
||
387 | |||
388 | public function setCreateInitialized(bool $createInitialized): static |
||
389 | { |
||
390 | self::$createInitialized = $createInitialized; |
||
391 | return $this; |
||
392 | } |
||
393 | |||
394 | public function getDefaultLeadingSpacer(): IFrame |
||
395 | { |
||
396 | return self::$defaultLeadingSpacer; |
||
397 | } |
||
398 | |||
399 | public function getDefaultTrailingSpacer(): IFrame |
||
402 | } |
||
403 | |||
404 | public function isAutoStartEnabled(): bool |
||
405 | { |
||
406 | return self::$autoStart; |
||
407 | } |
||
408 | |||
409 | public function setAutoStart(bool $autoStart): static |
||
410 | { |
||
411 | self::$autoStart = $autoStart; |
||
412 | return $this; |
||
413 | } |
||
414 | |||
415 | public function areSignalHandlersEnabled(): bool |
||
416 | { |
||
417 | return self::$attachSignalHandlers; |
||
418 | } |
||
419 | |||
420 | public function setAttachSignalHandlers(bool $attachSignalHandlers): static |
||
421 | { |
||
422 | self::$attachSignalHandlers = $attachSignalHandlers; |
||
423 | return $this; |
||
424 | } |
||
425 | |||
426 | public function getLoopProbeClasses(): iterable |
||
427 | { |
||
428 | return self::$loopProbes; |
||
429 | } |
||
430 | |||
431 | public function getTerminalProbeClasses(): iterable |
||
432 | { |
||
433 | return self::$terminalProbes; |
||
434 | } |
||
435 | |||
436 | /** @inheritdoc */ |
||
437 | public function setTerminalProbeClasses(iterable $terminalProbes): static |
||
438 | { |
||
439 | foreach ($terminalProbes as $probe) { |
||
440 | Asserter::isSubClass($probe, ITerminalProbe::class, __METHOD__); |
||
441 | } |
||
442 | self::$terminalProbes = $terminalProbes; |
||
443 | return $this; |
||
444 | } |
||
445 | |||
446 | /** @inheritdoc */ |
||
447 | public function setLoopProbeClasses(iterable $loopProbes): static |
||
454 | } |
||
455 | |||
456 | public function getTerminal(): ITerminal |
||
457 | { |
||
458 | return self::$terminal; |
||
459 | } |
||
460 | } |
||
461 |