Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Queue 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 Queue, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
48 | class Queue implements QueueInterface |
||
49 | { |
||
50 | |||
51 | const PRIORITY_HIGH = 'high'; |
||
52 | const PRIORITY_LOW = 'low'; |
||
53 | |||
54 | const NS_QUEUE = 'queue'; |
||
55 | const NS_QUEUE_STOP = 'queue2stop'; |
||
56 | const NS_MESSAGE = 'message'; |
||
57 | const NS_MESSAGE_TO_QUEUE = 'message2queue'; |
||
58 | const NS_MESSAGE_TO_STATE = 'message2state'; |
||
59 | |||
60 | // State |
||
61 | const STATE_READY = 'ready'; |
||
62 | const STATE_DELAYED = 'delayed'; |
||
63 | const STATE_RESERVED = 'reserved'; |
||
64 | const STATE_BURIED = 'buried'; |
||
65 | |||
66 | // Stats |
||
67 | const STATS_QUEUES_LIST = 'queues'; |
||
68 | const STATS_QUEUES = 'queues'; |
||
69 | const STATS_MESSAGE_TOTAL = 'total'; |
||
70 | const STATS_MESSAGE_READY = 'ready'; |
||
71 | const STATS_MESSAGE_RESERVED = 'reserved'; |
||
72 | const STATS_MESSAGE_DELAYED = 'delayed'; |
||
73 | const STATS_MESSAGE_BURIED = 'buried'; |
||
74 | const STATS_QUEUE_STOP = 'stop'; |
||
75 | |||
76 | /** |
||
77 | * @var \Predis\Client |
||
78 | */ |
||
79 | protected $redis; |
||
80 | |||
81 | /** |
||
82 | * @var string |
||
83 | */ |
||
84 | protected $namespace; |
||
85 | |||
86 | /** |
||
87 | * Queue constructor. |
||
88 | * |
||
89 | * @param mixed $redis |
||
90 | * @param string $namespace |
||
91 | */ |
||
92 | 33 | public function __construct($redis, $namespace = 'Quedis') |
|
97 | |||
98 | /** |
||
99 | * @return \Predis\Client |
||
100 | */ |
||
101 | 33 | public function getRedis() |
|
105 | |||
106 | /** |
||
107 | * @return string |
||
108 | */ |
||
109 | 1 | public function getNamespace() |
|
113 | |||
114 | /** |
||
115 | * @param string $queue |
||
116 | * @param mixed $data |
||
117 | * @param int $delay |
||
118 | * @param string $priority |
||
119 | * |
||
120 | * @return MessageInterface |
||
121 | * @throws \Exception |
||
122 | */ |
||
123 | 27 | public function put($queue, $data, $delay = 0, $priority = self::PRIORITY_LOW) |
|
154 | |||
155 | /** |
||
156 | * @param string $queue |
||
157 | * @param int $timeout |
||
158 | * |
||
159 | * @return mixed|null|Queue |
||
160 | */ |
||
161 | 11 | public function pop($queue, $timeout = 0) |
|
171 | |||
172 | /** |
||
173 | * @param string $queue |
||
174 | * @param int $timeout |
||
175 | * |
||
176 | * @return Message|null |
||
177 | */ |
||
178 | 21 | public function reserve($queue, $timeout = 0) |
|
201 | |||
202 | /** |
||
203 | * @param string $queue |
||
204 | * @param int $timeout |
||
205 | * |
||
206 | * @return null|string |
||
207 | */ |
||
208 | 20 | protected function reserveToken($queue, $timeout = 0) |
|
223 | |||
224 | /** |
||
225 | * @param string|null $token |
||
226 | * |
||
227 | * @return null|MessageInterface |
||
228 | */ |
||
229 | 20 | protected function restoreMessage($token) |
|
240 | |||
241 | /** |
||
242 | * @param string|MessageInterface $mixed |
||
243 | * |
||
244 | * @return $this |
||
245 | * @throws QueueException |
||
246 | */ |
||
247 | 3 | View Code Duplication | public function bury($mixed) |
265 | |||
266 | /** |
||
267 | * @param string|MessageInterface $mixed |
||
268 | * |
||
269 | * @return $this |
||
270 | * @throws QueueException |
||
271 | */ |
||
272 | 20 | public function delete($mixed) |
|
293 | |||
294 | /** |
||
295 | * @param MessageInterface|string $mixed |
||
296 | * |
||
297 | * @return $this |
||
298 | * @throws QueueException |
||
299 | */ |
||
300 | 3 | View Code Duplication | public function kick($mixed) |
318 | |||
319 | /** |
||
320 | * @param MessageInterface|string $mixed |
||
321 | * @param int $delay |
||
322 | * |
||
323 | * @return $this |
||
324 | * @throws FlowException |
||
325 | * @throws QueueException |
||
326 | */ |
||
327 | 2 | public function release($mixed, $delay = 0) |
|
352 | |||
353 | /** |
||
354 | * @return array |
||
355 | */ |
||
356 | 4 | public function getQueueList() |
|
365 | |||
366 | /** |
||
367 | * @param null|string $queue |
||
368 | * |
||
369 | * @return $this |
||
370 | */ |
||
371 | 21 | public function migrate($queue = null) |
|
407 | |||
408 | |||
409 | /** |
||
410 | * @param string $queue |
||
411 | * @param array $options |
||
412 | * |
||
413 | * @return Iterator |
||
414 | */ |
||
415 | 1 | public function iterator($queue, array $options = []) |
|
421 | |||
422 | /** |
||
423 | * @param string $queue |
||
424 | * |
||
425 | * @return $this |
||
426 | */ |
||
427 | 1 | public function start($queue) |
|
433 | |||
434 | /** |
||
435 | * @param string $queue |
||
436 | * |
||
437 | * @return $this |
||
438 | */ |
||
439 | 2 | public function stop($queue) |
|
445 | |||
446 | /** |
||
447 | * @param string $queue |
||
448 | * |
||
449 | * @return bool |
||
450 | */ |
||
451 | 24 | public function isStop($queue) |
|
455 | |||
456 | /** |
||
457 | * @param string $queue |
||
458 | * |
||
459 | * @return array |
||
460 | */ |
||
461 | 3 | protected function queueStats($queue) |
|
475 | |||
476 | /** |
||
477 | * @param null|string $queue |
||
478 | * |
||
479 | * @return array |
||
480 | */ |
||
481 | 5 | public function stats($queue = null) |
|
516 | |||
517 | /** |
||
518 | * @param string $queue |
||
519 | * @param string $state |
||
520 | * |
||
521 | * @return int|string |
||
522 | * @throws QueueException |
||
523 | */ |
||
524 | 4 | public function size($queue, $state = self::STATE_READY) |
|
536 | |||
537 | |||
538 | /** |
||
539 | * @param null|string $queue |
||
540 | * |
||
541 | * @return $this |
||
542 | */ |
||
543 | 33 | public function clean($queue = null) |
|
559 | |||
560 | /** |
||
561 | * @param mixed $mixed |
||
562 | * |
||
563 | * @return MessageInterface |
||
564 | */ |
||
565 | 27 | protected function createMessage($mixed) |
|
573 | |||
574 | /** |
||
575 | * @param string $type |
||
576 | * |
||
577 | * @return string |
||
578 | */ |
||
579 | 28 | protected function ns($type) |
|
583 | |||
584 | |||
585 | /** |
||
586 | * @param string $queue |
||
587 | * @param string $state |
||
588 | * |
||
589 | * @return string |
||
590 | */ |
||
591 | 27 | protected function getKey($queue, $state) |
|
595 | |||
596 | /** |
||
597 | * @param int|\DateTime $mixed |
||
598 | * |
||
599 | * @return int |
||
600 | */ |
||
601 | 27 | protected function parseDelay($mixed) |
|
611 | |||
612 | /** |
||
613 | * @param string $currentState |
||
614 | * @param string $action |
||
615 | * |
||
616 | * @return $this |
||
617 | * @throws FlowException |
||
618 | */ |
||
619 | 24 | protected function checkMessageFlow($currentState, $action) |
|
634 | |||
635 | /** |
||
636 | * @param string|MessageInterface $mixed |
||
637 | * |
||
638 | * @return Payload |
||
639 | * @throws QueueException |
||
640 | */ |
||
641 | 24 | protected function payload($mixed) |
|
650 | |||
651 | } |
||
652 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.