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 Scheduler 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 Scheduler, and based on these observations, apply Extract Interface, too.
1 | <?php namespace Indatus\Dispatcher\Drivers\DateTime; |
||
17 | class Scheduler extends Schedulable |
||
18 | { |
||
19 | const ANY = '*'; |
||
20 | |||
21 | const NONE = '-'; |
||
22 | |||
23 | private $scheduleWeek = self::NONE; |
||
24 | private $scheduleDayOfWeek = self::ANY; |
||
25 | private $scheduleMonth = self::ANY; |
||
26 | private $scheduleDayOfMonth = self::ANY; |
||
27 | private $scheduleHour = self::ANY; |
||
28 | private $scheduleMinute = self::ANY; |
||
29 | |||
30 | /** |
||
31 | * Get the scheduling definition in a readable way |
||
32 | * |
||
33 | * @return string |
||
34 | */ |
||
35 | 23 | public function getSchedule() |
|
46 | |||
47 | /** |
||
48 | * Get a valid cron schedule |
||
49 | * |
||
50 | * @return string |
||
51 | */ |
||
52 | 1 | public function getCronSchedule() |
|
61 | |||
62 | /** |
||
63 | * Manually set a command's execution schedule. Parameter |
||
64 | * order follows standard cron syntax |
||
65 | * |
||
66 | * @param int|array $minute |
||
67 | * @param int|array $hour |
||
68 | * @param int|array $dayOfMonth |
||
69 | * @param int|array $month |
||
70 | * @param int|array $dayOfWeek |
||
71 | * @param string|int|array $week |
||
72 | * |
||
73 | * @return $this |
||
74 | */ |
||
75 | 2 | public function setSchedule($minute, $hour, $dayOfMonth, $month, $dayOfWeek, $week = self::NONE) |
|
93 | |||
94 | /** |
||
95 | * Run once a year at midnight in the morning of January 1 |
||
96 | * |
||
97 | * @return $this |
||
98 | */ |
||
99 | 1 | public function yearly() |
|
110 | |||
111 | /** |
||
112 | * Run once a quarter at the beginning of the quarter |
||
113 | * |
||
114 | * @return $this |
||
115 | */ |
||
116 | 1 | public function quarterly() |
|
128 | |||
129 | /** |
||
130 | * Set the days of the month under which this command will run |
||
131 | * @param int|array $daysOfTheMonth |
||
132 | * @return $this |
||
133 | */ |
||
134 | 2 | public function daysOfTheMonth($daysOfTheMonth) |
|
140 | |||
141 | /** |
||
142 | * Run once a month at midnight in the morning of the first day of the month |
||
143 | * |
||
144 | * @return $this |
||
145 | */ |
||
146 | 1 | View Code Duplication | public function monthly() |
157 | |||
158 | /** |
||
159 | * Set the months under which this command will run |
||
160 | * @param int|array $monthsIntoTheYear |
||
161 | * @return $this |
||
162 | */ |
||
163 | 2 | public function months($monthsIntoTheYear) |
|
169 | |||
170 | /** |
||
171 | * Run a command every X months |
||
172 | * @param int $months |
||
173 | * @return $this |
||
174 | */ |
||
175 | 1 | public function everyMonths($months) |
|
181 | |||
182 | /** |
||
183 | * Run once every odd week at midnight on Sunday morning |
||
184 | * |
||
185 | * @return $this |
||
186 | */ |
||
187 | 1 | View Code Duplication | public function everyOddWeek() |
198 | |||
199 | /** |
||
200 | * Run once every even week at midnight on Sunday morning |
||
201 | * |
||
202 | * @return $this |
||
203 | */ |
||
204 | 1 | View Code Duplication | public function everyEvenWeek() |
215 | |||
216 | /** |
||
217 | * Run once a week at midnight on Sunday morning |
||
218 | * |
||
219 | * @return $this |
||
220 | */ |
||
221 | 1 | View Code Duplication | public function weekly() |
232 | |||
233 | /** |
||
234 | * Run on the given week of each month |
||
235 | * |
||
236 | * @param int|array $week |
||
237 | * |
||
238 | * @throws BadScheduleException |
||
239 | * |
||
240 | * @return $this |
||
241 | */ |
||
242 | 1 | public function week($week) |
|
248 | |||
249 | /** |
||
250 | * Run on the given week of each month |
||
251 | * |
||
252 | * @param int|array $week |
||
253 | * |
||
254 | * @throws BadScheduleException |
||
255 | * @return $this |
||
256 | */ |
||
257 | 1 | View Code Duplication | public function weekOfYear($week) |
268 | |||
269 | /** |
||
270 | * Run once a day at midnight |
||
271 | * |
||
272 | * @return $this |
||
273 | */ |
||
274 | 1 | View Code Duplication | public function daily() |
284 | |||
285 | /** |
||
286 | * Set the days of the week under which this command will run |
||
287 | * @param int|array $daysOfTheWeek |
||
288 | * @return $this |
||
289 | */ |
||
290 | 5 | public function daysOfTheWeek($daysOfTheWeek) |
|
296 | |||
297 | /** |
||
298 | * Run every weekday |
||
299 | * @return $this |
||
300 | */ |
||
301 | 3 | public function everyWeekday() |
|
307 | |||
308 | /** |
||
309 | * Run once an hour at the beginning of the hour |
||
310 | * |
||
311 | * @return $this |
||
312 | */ |
||
313 | 1 | View Code Duplication | public function hourly() |
323 | |||
324 | /** |
||
325 | * Set the hours under which this command will run |
||
326 | * @param int|array $hoursIntoTheDay |
||
327 | * @return $this |
||
328 | */ |
||
329 | 2 | public function hours($hoursIntoTheDay) |
|
335 | |||
336 | /** |
||
337 | * Run a command every X hours |
||
338 | * @param int $hours |
||
339 | * @return $this |
||
340 | */ |
||
341 | 1 | public function everyHours($hours) |
|
347 | |||
348 | /** |
||
349 | * Set the minutes under which this command will run |
||
350 | * @param int|array $minutesIntoTheHour |
||
351 | * @return $this |
||
352 | */ |
||
353 | 2 | public function minutes($minutesIntoTheHour) |
|
359 | |||
360 | /** |
||
361 | * Run a command every X minutes |
||
362 | * @param int $minutes |
||
363 | * @return $this |
||
364 | */ |
||
365 | 1 | public function everyMinutes($minutes) |
|
376 | |||
377 | /** |
||
378 | * @inheritDoc |
||
379 | * @return Scheduler |
||
380 | */ |
||
381 | 3 | public function args(array $arguments) |
|
385 | |||
386 | /** |
||
387 | * @inheritDoc |
||
388 | * @return Scheduler |
||
389 | */ |
||
390 | 2 | public function opts(array $options) |
|
394 | |||
395 | /** |
||
396 | * If an array of values is used, convert it |
||
397 | * to a comma separated value. |
||
398 | */ |
||
399 | 14 | protected function parseTimeParameter($parameter) |
|
407 | |||
408 | /** |
||
409 | * @param string $scheduleWeek |
||
410 | */ |
||
411 | 10 | protected function setScheduleWeek($scheduleWeek) |
|
415 | |||
416 | /** |
||
417 | * @return string |
||
418 | */ |
||
419 | 23 | public function getScheduleWeek() |
|
423 | |||
424 | /** |
||
425 | * @param string $scheduleDayOfMonth |
||
426 | */ |
||
427 | 13 | protected function setScheduleDayOfMonth($scheduleDayOfMonth) |
|
431 | |||
432 | /** |
||
433 | * @return string |
||
434 | */ |
||
435 | 23 | public function getScheduleDayOfMonth() |
|
439 | |||
440 | /** |
||
441 | * @param string $scheduleDayOfWeek |
||
442 | */ |
||
443 | 16 | protected function setScheduleDayOfWeek($scheduleDayOfWeek) |
|
447 | |||
448 | /** |
||
449 | * @return string |
||
450 | */ |
||
451 | 24 | public function getScheduleDayOfWeek() |
|
455 | |||
456 | /** |
||
457 | * @param string $scheduleHour |
||
458 | */ |
||
459 | 14 | protected function setScheduleHour($scheduleHour) |
|
463 | |||
464 | /** |
||
465 | * @return string |
||
466 | */ |
||
467 | 23 | public function getScheduleHour() |
|
471 | |||
472 | /** |
||
473 | * @param string $scheduleMinute |
||
474 | */ |
||
475 | 14 | protected function setScheduleMinute($scheduleMinute) |
|
479 | |||
480 | /** |
||
481 | * @return string |
||
482 | */ |
||
483 | 23 | public function getScheduleMinute() |
|
487 | |||
488 | /** |
||
489 | * @param string $scheduleMonth |
||
490 | */ |
||
491 | 14 | protected function setScheduleMonth($scheduleMonth) |
|
495 | |||
496 | /** |
||
497 | * @return string |
||
498 | */ |
||
499 | 23 | public function getScheduleMonth() |
|
503 | |||
504 | /** |
||
505 | * @return string |
||
506 | */ |
||
507 | 1 | public function __toString() |
|
511 | } |
||
512 |
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.