Complex classes like Runner 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 Runner, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 38 | class Runner { |
||
| 39 | |||
| 40 | const TICK_TTL = 1800; |
||
| 41 | |||
| 42 | const TICK_MINIMUM = 2; |
||
| 43 | const TICK_UPDATE = 10; |
||
| 44 | const MEMORY_UPDATE = 5; |
||
| 45 | |||
| 46 | const RESULT_TYPE_SUCCESS = 1; |
||
| 47 | const RESULT_TYPE_WARNING = 4; |
||
| 48 | const RESULT_TYPE_FAIL = 9; |
||
| 49 | |||
| 50 | /** @var RunningService */ |
||
| 51 | private $runningService; |
||
| 52 | |||
| 53 | /** @var string */ |
||
| 54 | private $source; |
||
| 55 | |||
| 56 | // /** @var bool */ |
||
| 57 | // private $strict = false; |
||
| 58 | |||
| 59 | /** @var int */ |
||
| 60 | private $tickId; |
||
| 61 | |||
| 62 | /** @var ExtendedBase */ |
||
| 63 | private $commandBase = null; |
||
| 64 | |||
| 65 | /** @var OutputInterface */ |
||
| 66 | private $outputInterface = null; |
||
| 67 | |||
| 68 | /** @var array */ |
||
| 69 | private $info = []; |
||
| 70 | |||
| 71 | /** @var int */ |
||
| 72 | private $oldTick = 0; |
||
| 73 | |||
| 74 | /** @var string */ |
||
| 75 | private $oldAction = ''; |
||
| 76 | |||
| 77 | /** @var int */ |
||
| 78 | private $ramUpdate = 0; |
||
| 79 | |||
| 80 | /** @var int */ |
||
| 81 | private $tickUpdate = 0; |
||
| 82 | |||
| 83 | /** @var array */ |
||
| 84 | private $methodOnKeyPress = []; |
||
| 85 | |||
| 86 | /** @var array */ |
||
| 87 | private $methodOnInfoUpdate = []; |
||
| 88 | |||
| 89 | /** @var array */ |
||
| 90 | private $methodOnIndexError = []; |
||
| 91 | |||
| 92 | /** @var array */ |
||
| 93 | private $methodOnIndexResult = []; |
||
| 94 | |||
| 95 | /** @var bool */ |
||
| 96 | private $paused = false; |
||
| 97 | |||
| 98 | /** @var bool */ |
||
| 99 | private $pauseRunning = false; |
||
| 100 | |||
| 101 | /** @var array */ |
||
| 102 | private $keys = ['nextStep' => 'n']; |
||
| 103 | |||
| 104 | |||
| 105 | /** |
||
| 106 | * Runner constructor. |
||
| 107 | * |
||
| 108 | * @param RunningService $runningService |
||
| 109 | * @param string $source |
||
| 110 | * @param array $keys |
||
| 111 | */ |
||
| 112 | public function __construct(RunningService $runningService, $source, $keys = []) { |
||
| 113 | $this->runningService = $runningService; |
||
| 114 | $this->source = $source; |
||
| 115 | |||
| 116 | if (sizeof($keys) > 0) { |
||
| 117 | $this->keys = $keys; |
||
| 118 | } |
||
| 119 | } |
||
| 120 | |||
| 121 | |||
| 122 | /** |
||
| 123 | * @throws RunnerAlreadyUpException |
||
| 124 | */ |
||
| 125 | public function start() { |
||
| 126 | // $this->strict = $strict; |
||
| 127 | $this->tickId = $this->runningService->start($this->source); |
||
| 128 | } |
||
| 129 | |||
| 130 | |||
| 131 | /** |
||
| 132 | * @param string $action |
||
| 133 | * @param bool $force |
||
| 134 | * |
||
| 135 | * @return string |
||
| 136 | * @throws \Exception |
||
| 137 | */ |
||
| 138 | public function updateAction($action = '', $force = false) { |
||
| 139 | $n = ''; |
||
| 140 | if (sizeof($this->methodOnKeyPress) > 0) { |
||
| 141 | $n = fread(STDIN, 9999); |
||
| 142 | if ($n !== '') { |
||
| 143 | $n = substr($n, 0, 1); |
||
| 144 | $this->keyPressed($n); |
||
| 145 | } |
||
| 146 | } |
||
| 147 | |||
| 148 | if ($action === '') { |
||
| 149 | return $n; |
||
| 150 | } |
||
| 151 | |||
| 152 | $tick = time(); |
||
| 153 | // try { |
||
| 154 | // $this->hasBeenInterrupted(); |
||
| 155 | // } catch (InterruptException $e) { |
||
| 156 | // $this->stop(); |
||
| 157 | // throw $e; |
||
| 158 | // } |
||
| 159 | |||
| 160 | if ($this->oldAction !== $action || $force) { |
||
| 161 | while (true) { |
||
| 162 | if (!$this->isPaused()) { |
||
| 163 | break; |
||
| 164 | } |
||
| 165 | |||
| 166 | $this->pauseRunning(true); |
||
| 167 | $pressed = strtolower($this->updateAction('')); |
||
| 168 | if ($pressed === $this->keys['nextStep']) { |
||
| 169 | break; |
||
| 170 | } |
||
| 171 | usleep(300000); |
||
| 172 | } |
||
| 173 | |||
| 174 | $this->pauseRunning(false); |
||
| 175 | } |
||
| 176 | |||
| 177 | if ($this->oldAction === $action && ($this->oldTick + self::TICK_MINIMUM > $tick)) { |
||
| 178 | return ''; |
||
| 179 | } |
||
| 180 | |||
| 181 | $this->setInfo('action', $action); |
||
| 182 | |||
| 183 | $this->updateTick($tick, $action); |
||
| 184 | $this->updateRamInfo($tick); |
||
| 185 | |||
| 186 | $this->oldAction = $action; |
||
| 187 | $this->oldTick = $tick; |
||
| 188 | |||
| 189 | return ''; |
||
| 190 | } |
||
| 191 | |||
| 192 | |||
| 193 | /** |
||
| 194 | * @param string $info |
||
| 195 | * @param string $value |
||
| 196 | * @param int $type |
||
| 197 | */ |
||
| 198 | public function setInfo($info, $value, $type = 0) { |
||
| 203 | |||
| 204 | /** |
||
| 205 | * @param array $data |
||
| 206 | */ |
||
| 207 | public function setInfoArray($data) { |
||
| 216 | |||
| 217 | |||
| 218 | /** |
||
| 219 | * @param string $info |
||
| 220 | * @param int $level |
||
| 221 | */ |
||
| 222 | public function setInfoColored($info, $level) { |
||
| 223 | |||
| 224 | $value = $this->getInfo($info); |
||
| 225 | if ($value === '') { |
||
| 226 | return; |
||
| 227 | } |
||
| 228 | |||
| 229 | $color = ''; |
||
| 230 | switch ($level) { |
||
| 231 | case self::RESULT_TYPE_SUCCESS: |
||
| 232 | $color = 'info'; |
||
| 233 | break; |
||
| 234 | |||
| 235 | case self::RESULT_TYPE_WARNING: |
||
| 236 | $color = 'comment'; |
||
| 237 | break; |
||
| 238 | |||
| 239 | case self::RESULT_TYPE_FAIL: |
||
| 240 | $color = 'error'; |
||
| 241 | break; |
||
| 242 | } |
||
| 243 | |||
| 244 | if ($color !== '') { |
||
| 245 | $this->info[$info . 'Colored'] = '<' . $color . '>' . $value . '</' . $color . '>'; |
||
| 246 | } |
||
| 247 | |||
| 248 | |||
| 249 | } |
||
| 250 | |||
| 251 | /** |
||
| 252 | * @return array |
||
| 253 | */ |
||
| 254 | public function getInfoAll() { |
||
| 255 | return $this->info; |
||
| 256 | } |
||
| 257 | |||
| 258 | |||
| 259 | /** |
||
| 260 | * @param string $k |
||
| 261 | * |
||
| 262 | * @return string |
||
|
|
|||
| 263 | */ |
||
| 264 | public function getInfo($k) { |
||
| 265 | return MiscService::get($k, $this->info, ''); |
||
| 266 | } |
||
| 267 | |||
| 268 | |||
| 269 | /** |
||
| 270 | * @param array $method |
||
| 271 | */ |
||
| 272 | public function onKeyPress($method) { |
||
| 273 | $this->methodOnKeyPress[] = $method; |
||
| 274 | } |
||
| 275 | |||
| 276 | /** |
||
| 277 | * @param $key |
||
| 278 | */ |
||
| 279 | public function keyPressed($key) { |
||
| 280 | foreach ($this->methodOnKeyPress as $method) { |
||
| 281 | call_user_func($method, $key); |
||
| 282 | } |
||
| 283 | } |
||
| 284 | |||
| 285 | |||
| 286 | /** |
||
| 287 | * @param array $method |
||
| 288 | */ |
||
| 289 | public function onInfoUpdate($method) { |
||
| 292 | |||
| 293 | |||
| 294 | public function infoUpdated() { |
||
| 295 | foreach ($this->methodOnInfoUpdate as $method) { |
||
| 296 | call_user_func($method, $this->info); |
||
| 297 | } |
||
| 298 | } |
||
| 299 | |||
| 300 | |||
| 301 | /** |
||
| 302 | * @param array $method |
||
| 303 | */ |
||
| 304 | public function onNewIndexError($method) { |
||
| 307 | |||
| 308 | /** |
||
| 309 | * @param Index $index |
||
| 310 | * @param string $message |
||
| 311 | * @param string $class |
||
| 312 | * @param int $sev |
||
| 313 | */ |
||
| 314 | public function newIndexError($index, $message, $class = '', $sev = 3) { |
||
| 326 | |||
| 327 | |||
| 328 | /** |
||
| 329 | * @param array $method |
||
| 330 | */ |
||
| 331 | public function onNewIndexResult($method) { |
||
| 334 | |||
| 335 | |||
| 336 | /** |
||
| 337 | * @param Index $index |
||
| 338 | * @param string $message |
||
| 339 | * @param string $status |
||
| 340 | * @param int $type |
||
| 341 | */ |
||
| 342 | public function newIndexResult($index, $message, $status, $type) { |
||
| 354 | |||
| 355 | |||
| 356 | // /** |
||
| 357 | // * @throws InterruptException |
||
| 358 | // */ |
||
| 359 | // private function hasBeenInterrupted() { |
||
| 360 | // if ($this->commandBase === null) { |
||
| 361 | // return; |
||
| 362 | // } |
||
| 363 | // $this->commandBase->hasBeenInterrupted(); |
||
| 364 | // } |
||
| 365 | |||
| 366 | |||
| 367 | /** |
||
| 368 | * @param int $tick |
||
| 369 | * @param string $action |
||
| 370 | * |
||
| 371 | * @throws TickDoesNotExistException |
||
| 372 | */ |
||
| 373 | private function updateTick($tick, $action) { |
||
| 387 | |||
| 388 | |||
| 389 | /** |
||
| 390 | * @param $tick |
||
| 391 | */ |
||
| 392 | private function updateRamInfo($tick) { |
||
| 400 | |||
| 401 | |||
| 402 | /** |
||
| 403 | * @deprecated - verifier l'interet !? |
||
| 404 | * |
||
| 405 | * @param $reason |
||
| 406 | * @param $stop |
||
| 407 | */ |
||
| 408 | public function exception($reason, $stop) { |
||
| 415 | |||
| 416 | |||
| 417 | /** |
||
| 418 | * @throws TickDoesNotExistException |
||
| 419 | */ |
||
| 420 | public function stop() { |
||
| 423 | |||
| 424 | |||
| 425 | /** |
||
| 426 | * @param ExtendedBase $base |
||
| 427 | * @param OutputInterface $output |
||
| 428 | */ |
||
| 429 | public function sourceIsCommandLine(ExtendedBase $base, OutputInterface $output) { |
||
| 433 | |||
| 434 | |||
| 435 | /** |
||
| 436 | * @param bool $pause |
||
| 437 | */ |
||
| 438 | public function pause($pause) { |
||
| 442 | |||
| 443 | /** |
||
| 444 | * @return bool |
||
| 445 | */ |
||
| 446 | public function isPaused() { |
||
| 449 | |||
| 450 | |||
| 451 | /** |
||
| 452 | * @param bool $running |
||
| 453 | */ |
||
| 454 | public function pauseRunning($running) { |
||
| 458 | |||
| 459 | |||
| 460 | public function isPauseRunning() { |
||
| 463 | |||
| 464 | |||
| 465 | // /** |
||
| 466 | // * @return bool |
||
| 467 | // */ |
||
| 468 | // public function isStrict() { |
||
| 469 | // return $this->strict; |
||
| 470 | // } |
||
| 471 | |||
| 472 | /** |
||
| 473 | * @param string $line |
||
| 474 | */ |
||
| 475 | public function output($line) { |
||
| 482 | |||
| 483 | |||
| 484 | } |
||
| 485 |
This check compares the return type specified in the
@returnannotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.If the return type contains the type array, this check recommends the use of a more specific type like
String[]orarray<String>.