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 WorkingTime 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 WorkingTime, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
23 | class WorkingTime |
||
24 | { |
||
25 | /** |
||
26 | * @var \DateTime |
||
27 | */ |
||
28 | public $dateTime; |
||
29 | |||
30 | /** |
||
31 | * @var array |
||
32 | */ |
||
33 | public $workingDays; |
||
34 | |||
35 | /** |
||
36 | * @var array |
||
37 | */ |
||
38 | public $weekends; |
||
39 | |||
40 | /** |
||
41 | * @var array |
||
42 | */ |
||
43 | public $holidays; |
||
44 | |||
45 | /** |
||
46 | * WorkingTime constructor. |
||
47 | * |
||
48 | * @param array $workTimeConfig |
||
49 | * @param string $dateTime |
||
50 | */ |
||
51 | 13 | public function __construct(array $workTimeConfig, string $dateTime = 'now') |
|
58 | |||
59 | /** |
||
60 | * Фурмирует строку дня. |
||
61 | * |
||
62 | * @param string|null $date |
||
63 | * @param string $format |
||
64 | * @return string |
||
65 | */ |
||
66 | 10 | private function buildDataPartString(string $date = null, string $format) : string |
|
76 | |||
77 | /** |
||
78 | * Формирует дату из строки. |
||
79 | * |
||
80 | * @param string $date |
||
81 | * @return \DateTime |
||
82 | */ |
||
83 | 7 | private function buildDate(string $date = null) : \DateTime |
|
91 | |||
92 | /** |
||
93 | * Проверяет является ли дата праздничным днём. |
||
94 | * |
||
95 | * @param string $date |
||
96 | * @return bool |
||
97 | */ |
||
98 | 10 | View Code Duplication | public function isHoliday(string $date = null) : bool |
108 | |||
109 | /** |
||
110 | * Проверяет является ли дата выходным днём. |
||
111 | * |
||
112 | * @param string $date |
||
113 | * @return bool |
||
114 | */ |
||
115 | 10 | View Code Duplication | public function isWeekend(string $date = null) : bool |
125 | |||
126 | /** |
||
127 | * Проверяет евляется ли дата рабочим днём. |
||
128 | * |
||
129 | * Формат даты - "Y-m-d" |
||
130 | * @param string $date |
||
131 | * @return bool |
||
132 | */ |
||
133 | 9 | public function isWorkingDate(string $date = null) : bool |
|
143 | |||
144 | /** |
||
145 | * Проверяет евляется ли время рабочим. |
||
146 | * |
||
147 | * @param string|null $time Формат времени - "H:i" или полный "Y-m-d H:i" |
||
148 | * @return bool |
||
149 | * @throws \InvalidArgumentException |
||
150 | */ |
||
151 | 2 | public function isWorkingTime(string $time = null) : bool |
|
172 | |||
173 | /** |
||
174 | * Возвращает следующий рабочий день. |
||
175 | * |
||
176 | * @param string|null $date Формат даты - "Y-m-d" |
||
177 | * @return string |
||
178 | */ |
||
179 | 4 | public function nextWorkingDay(string $date = null) : string |
|
193 | |||
194 | /** |
||
195 | * Возвращает ближайшее рабочее время. Либо пустую строку если текущее время уже рабочее |
||
196 | * |
||
197 | * @param string|null $date |
||
198 | * @return string |
||
199 | */ |
||
200 | 7 | public function nextWorkingTime(string $date = null) : string |
|
236 | |||
237 | /** |
||
238 | * Возвращает длинну рабочего дня в минутах. |
||
239 | * |
||
240 | * @param string|null $date Формат даты - "Y-m-d" |
||
241 | * @return int |
||
242 | */ |
||
243 | 6 | public function getJobMinutesInDay(string $date = null) : int |
|
261 | |||
262 | /** |
||
263 | * Прибавляет заданное количество минут к дате с учетом рабочего времени. |
||
264 | * |
||
265 | * @param int $minutes |
||
266 | * @param string $date |
||
267 | * @return \DateTime |
||
268 | */ |
||
269 | 3 | private function modifyDate(int $minutes, string $date) : \DateTime |
|
293 | |||
294 | /** |
||
295 | * Прибавляет заданное количество минут к дате с учетом рабочего времени. |
||
296 | * |
||
297 | * @param int $minutes |
||
298 | * @param string $date |
||
299 | * @return string |
||
300 | */ |
||
301 | 3 | public function modify(int $minutes, string $date = null) : string |
|
315 | |||
316 | /** |
||
317 | * Возвращает рабочее время в минутах в заданном временном интервале. |
||
318 | * |
||
319 | * @param string $startDate |
||
320 | * @param string $endDate |
||
321 | * @return int |
||
322 | * @throws \InvalidArgumentException |
||
323 | */ |
||
324 | 1 | public function calculatingWorkingTime(string $startDate, string $endDate) : int |
|
346 | |||
347 | /** |
||
348 | * Проверяет является ли строка корректной датой. |
||
349 | * |
||
350 | * @param $date |
||
351 | * @param string $format |
||
352 | * @return bool |
||
353 | */ |
||
354 | 4 | public static function validateDate(string $date, string $format = 'Y-m-d H:i:s') : bool |
|
359 | } |
||
360 |
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.