Complex classes like TaskBag 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 TaskBag, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
11 | class TaskBag implements TaskBagInterface |
||
12 | { |
||
13 | /** @var string Task */ |
||
14 | protected $task; |
||
15 | |||
16 | /** @var array */ |
||
17 | protected $environments = [TaskPlanner::PRODUCTION_ENVIRONMENT, TaskPlanner::DEVELOPMENT_ENVIRONMENT]; |
||
18 | |||
19 | /** @var array|string Tasks that must follow this one */ |
||
20 | protected $followedBy = []; |
||
21 | |||
22 | /** @var CronExpression */ |
||
23 | protected $cronExpression; |
||
24 | |||
25 | /* Expressions */ |
||
26 | /** @var null|string */ |
||
27 | protected $interval = null; // @daily, @yearly |
||
28 | |||
29 | /** @var null|string|int|array */ |
||
30 | protected $minute = null; |
||
31 | |||
32 | /** @var null|string|int|array */ |
||
33 | protected $hour = null; |
||
34 | |||
35 | /** @var null|string|int|array */ |
||
36 | protected $month = null; // 12 |
||
37 | |||
38 | /** @var null|string|int|array */ |
||
39 | protected $day = null; // 25 |
||
40 | |||
41 | /** @var null|string|int|array */ |
||
42 | protected $weekday = null; |
||
43 | |||
44 | /* Dependencies */ |
||
45 | /** @var ExpressionBuilderInterface */ |
||
46 | protected $expressionBuilder; |
||
47 | |||
48 | |||
49 | /** |
||
50 | * TaskBag constructor. |
||
51 | * @param string $task |
||
52 | */ |
||
53 | 40 | public function __construct($task = null) |
|
67 | |||
68 | /** |
||
69 | * @return string |
||
70 | */ |
||
71 | 4 | public function getTask() |
|
75 | |||
76 | /** |
||
77 | * @param string $task |
||
78 | * @return $this |
||
79 | */ |
||
80 | 29 | public function setTask($task) |
|
85 | |||
86 | /** |
||
87 | * @return null|string |
||
88 | */ |
||
89 | 14 | public function getInterval() |
|
93 | |||
94 | /** |
||
95 | * @param string $interval |
||
96 | * @return $this |
||
97 | */ |
||
98 | 15 | public function setInterval($interval) |
|
103 | |||
104 | /** |
||
105 | * Parses a time from format 12:14 |
||
106 | * @param $time |
||
107 | * @return $this |
||
108 | */ |
||
109 | 5 | public function setTime($time) |
|
117 | |||
118 | /** |
||
119 | * @param string $time |
||
120 | * @return $this |
||
121 | */ |
||
122 | 12 | public function addTime($time) |
|
130 | |||
131 | /** |
||
132 | * Parses a time from formats 11/15 or 11-15 |
||
133 | * @param string $date |
||
134 | * @return $this |
||
135 | */ |
||
136 | 2 | public function setDate($date) |
|
|
|||
137 | { |
||
138 | 2 | $parts = $this->parseDate($date); |
|
139 | 2 | $this->setMonth(intval($parts[0])); |
|
140 | 2 | $this->setDay(intval($parts[1])); |
|
141 | |||
142 | 2 | return $this; |
|
143 | } |
||
144 | |||
145 | /** |
||
146 | * @param string $date |
||
147 | * @return $this |
||
148 | */ |
||
149 | 4 | public function addDate($date) |
|
150 | { |
||
151 | 4 | $parts = $this->parseDate($date); |
|
152 | 4 | $this->addMonth(intval($parts[0])); |
|
153 | 4 | $this->addDay(intval($parts[1])); |
|
154 | |||
155 | 4 | return $this; |
|
156 | } |
||
157 | |||
158 | /** |
||
159 | * @param integer $month |
||
160 | * @return $this |
||
161 | */ |
||
162 | 6 | public function setMonth($month) |
|
167 | |||
168 | /** |
||
169 | * @return int|bool|string |
||
170 | */ |
||
171 | 14 | public function getMonth() |
|
175 | |||
176 | /** |
||
177 | * @param string|int|array $month |
||
178 | * @return $this |
||
179 | */ |
||
180 | 7 | public function addMonth($month) |
|
185 | |||
186 | /** |
||
187 | * @param integer $day |
||
188 | * @return $this |
||
189 | */ |
||
190 | 8 | public function setDay($day) |
|
195 | |||
196 | /** |
||
197 | * @return int|null|string |
||
198 | */ |
||
199 | 14 | public function getDay() |
|
203 | |||
204 | /** |
||
205 | * @param string|int|array $day |
||
206 | * @return $this |
||
207 | */ |
||
208 | 9 | public function addDay($day) |
|
213 | |||
214 | /** |
||
215 | * @param string|int|array $minute |
||
216 | * @return $this |
||
217 | * @throws \Exception |
||
218 | */ |
||
219 | 8 | public function setMinute($minute) |
|
224 | |||
225 | /** |
||
226 | * @return int|null|string |
||
227 | */ |
||
228 | 14 | public function getMinute() |
|
232 | |||
233 | /** |
||
234 | * @param string|int|array $minute |
||
235 | * @return $this |
||
236 | */ |
||
237 | 13 | public function addMinute($minute) |
|
242 | |||
243 | /** |
||
244 | * @param string|int|array $hour |
||
245 | * @return $this |
||
246 | */ |
||
247 | 8 | public function setHour($hour) |
|
252 | |||
253 | /** |
||
254 | * @return int|null|string |
||
255 | */ |
||
256 | 14 | public function getHour() |
|
260 | |||
261 | /** |
||
262 | * @param string|int|array $hour |
||
263 | * @return $this |
||
264 | */ |
||
265 | 13 | public function addHour($hour) |
|
270 | |||
271 | /** |
||
272 | * @param string|int|array $weekday |
||
273 | * @return $this |
||
274 | */ |
||
275 | 2 | public function setWeekday($weekday) |
|
280 | |||
281 | /** |
||
282 | * @return int|null|string |
||
283 | */ |
||
284 | 10 | public function getWeekday() |
|
288 | |||
289 | /** |
||
290 | * @param string|int|array $weekday |
||
291 | * @return $this |
||
292 | */ |
||
293 | 3 | public function addWeekday($weekday) |
|
298 | |||
299 | 5 | public function setEnvironments($environments) |
|
308 | |||
309 | /** |
||
310 | * @param string $environment |
||
311 | * @return $this |
||
312 | */ |
||
313 | 2 | public function addEnvironment($environment) |
|
318 | |||
319 | /** |
||
320 | * @return array |
||
321 | */ |
||
322 | 4 | public function getEnvironments() |
|
326 | |||
327 | /** |
||
328 | * @param string $task |
||
329 | * @return $this |
||
330 | */ |
||
331 | 7 | public function addFollowedBy($task) |
|
336 | |||
337 | /** |
||
338 | * @return array |
||
339 | */ |
||
340 | 3 | public function getFollowedBy() |
|
344 | |||
345 | /** |
||
346 | * @param string $followedBy |
||
347 | * @return $this |
||
348 | */ |
||
349 | 3 | public function setFollowedBy($followedBy) |
|
354 | |||
355 | /** |
||
356 | * @param string|CronExpression $cronExpression |
||
357 | * @return $this |
||
358 | */ |
||
359 | 16 | public function setCronExpression($cronExpression) |
|
367 | |||
368 | /** |
||
369 | * @return CronExpression |
||
370 | */ |
||
371 | 12 | public function getCronExpression() |
|
375 | |||
376 | /** |
||
377 | * @return CronExpression |
||
378 | */ |
||
379 | 8 | protected function buildExpression() |
|
385 | |||
386 | /** |
||
387 | * @param ExpressionBuilderInterface $expressionBuilder |
||
388 | */ |
||
389 | 1 | public function setExpressionBuilder(ExpressionBuilderInterface $expressionBuilder) |
|
393 | |||
394 | /** |
||
395 | * @return ExpressionBuilder|ExpressionBuilderInterface |
||
396 | */ |
||
397 | 8 | protected function getExpressionBuilder() |
|
401 | |||
402 | |||
403 | /* Just passed through to CronExpression */ |
||
404 | /** |
||
405 | * @param string $currentTime |
||
406 | * @return bool |
||
407 | */ |
||
408 | 2 | public function isDue($currentTime = 'now') |
|
412 | |||
413 | /** |
||
414 | * @param string $currentTime |
||
415 | * @param int $nth |
||
416 | * @param bool $allowCurrentDate |
||
417 | */ |
||
418 | public function getNextRunDate($currentTime = 'now', $nth = 0, $allowCurrentDate = false) |
||
422 | |||
423 | /** |
||
424 | * @param string $currentTime |
||
425 | * @param int $nth |
||
426 | * @param bool $allowCurrentDate |
||
427 | */ |
||
428 | public function getPreviousRunDate($currentTime = 'now', $nth = 0, $allowCurrentDate = false) |
||
432 | |||
433 | /* Internals */ |
||
434 | /** |
||
435 | * @param $time |
||
436 | * @return array |
||
437 | */ |
||
438 | 14 | protected function parseTime($time) |
|
443 | |||
444 | /** |
||
445 | * @param string $date |
||
446 | * @return array |
||
447 | */ |
||
448 | 6 | protected function parseDate($date) |
|
458 | |||
459 | /** |
||
460 | * @param string $key |
||
461 | * @param $value |
||
462 | * @param string $deliminator |
||
463 | */ |
||
464 | 21 | protected function appendValue($key, $value, $deliminator = ',') |
|
476 | |||
477 | /** |
||
478 | * @param $value |
||
479 | * @return array |
||
480 | * @internal param $minute |
||
481 | */ |
||
482 | 21 | protected function forceToArray($value) |
|
490 | } |
||
491 |
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.