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:
1 | <?php |
||
28 | class Storage |
||
29 | { |
||
30 | /** |
||
31 | * Type folder on computer (local/network). |
||
32 | * |
||
33 | * @var string |
||
34 | */ |
||
35 | const TYPE_FOLDER = 'folder'; |
||
36 | |||
37 | /** |
||
38 | * Type external storage (HDD/Flash/SD). |
||
39 | * |
||
40 | * @var string |
||
41 | */ |
||
42 | const TYPE_EXTERNAL = 'external'; |
||
43 | |||
44 | /** |
||
45 | * Type external storage read-only (CD/DVD). |
||
46 | * |
||
47 | * @var string |
||
48 | */ |
||
49 | const TYPE_EXTERNAL_R = 'external-r'; |
||
50 | |||
51 | /** |
||
52 | * Type video storage (DVD/BD/VHS). |
||
53 | * |
||
54 | * @var string |
||
55 | */ |
||
56 | const TYPE_VIDEO = 'video'; |
||
57 | |||
58 | /** |
||
59 | * @ORM\Id |
||
60 | * @ORM\GeneratedValue |
||
61 | * @ORM\Column(type="integer") |
||
62 | * |
||
63 | * @var int |
||
64 | */ |
||
65 | protected $id = 0; |
||
66 | |||
67 | /** |
||
68 | * @ORM\Column(type="string", length=128) |
||
69 | * @Assert\NotBlank() |
||
70 | * |
||
71 | * @var string |
||
72 | */ |
||
73 | protected $name = ''; |
||
74 | |||
75 | /** |
||
76 | * @ORM\Column(type="text", nullable=true) |
||
77 | * |
||
78 | * @var string |
||
79 | */ |
||
80 | protected $description = ''; |
||
81 | |||
82 | /** |
||
83 | * @ORM\Column(type="string", length=16) |
||
84 | * @Assert\Choice(callback = "getTypes") |
||
85 | * |
||
86 | * @var string |
||
87 | */ |
||
88 | protected $type = ''; |
||
89 | |||
90 | /** |
||
91 | * Path on computer. |
||
92 | * |
||
93 | * @ORM\Column(type="text", nullable=true) |
||
94 | * |
||
95 | * @var string |
||
96 | */ |
||
97 | protected $path = ''; |
||
98 | |||
99 | /** |
||
100 | * Date last update storage. |
||
101 | * |
||
102 | * @ORM\Column(type="datetime") |
||
103 | * |
||
104 | * @var \DateTime |
||
105 | */ |
||
106 | protected $date_update; |
||
107 | |||
108 | /** |
||
109 | * Date of files last modified. |
||
110 | * |
||
111 | * @ORM\Column(type="datetime") |
||
112 | * |
||
113 | * @var \DateTime |
||
114 | */ |
||
115 | protected $file_modified; |
||
116 | |||
117 | /** |
||
118 | * @ORM\OneToMany(targetEntity="Item", mappedBy="storage") |
||
119 | * |
||
120 | * @var ArrayCollection |
||
121 | */ |
||
122 | protected $items; |
||
123 | |||
124 | /** |
||
125 | * List old paths. |
||
126 | * |
||
127 | * @var array |
||
128 | */ |
||
129 | protected $old_paths = []; |
||
130 | |||
131 | /** |
||
132 | * @var array |
||
133 | */ |
||
134 | protected static $type_names = [ |
||
135 | self::TYPE_FOLDER, |
||
136 | self::TYPE_EXTERNAL, |
||
137 | self::TYPE_EXTERNAL_R, |
||
138 | self::TYPE_VIDEO, |
||
139 | ]; |
||
140 | |||
141 | /** |
||
142 | * @var array |
||
143 | */ |
||
144 | protected static $type_titles = [ |
||
145 | self::TYPE_FOLDER => 'Folder on computer (local/network)', |
||
146 | self::TYPE_EXTERNAL => 'External storage (HDD/Flash/SD)', |
||
147 | self::TYPE_EXTERNAL_R => 'External storage read-only (CD/DVD)', |
||
148 | self::TYPE_VIDEO => 'Video storage (DVD/BD/VHS)', |
||
149 | ]; |
||
150 | |||
151 | 149 | public function __construct() |
|
156 | |||
157 | /** |
||
158 | * @return int |
||
159 | */ |
||
160 | 1 | public function getId() |
|
164 | |||
165 | /** |
||
166 | * @param string $name |
||
167 | * |
||
168 | * @return Storage |
||
169 | */ |
||
170 | 2 | public function setName($name) |
|
176 | |||
177 | /** |
||
178 | * @return string |
||
179 | */ |
||
180 | 2 | public function getName() |
|
184 | |||
185 | /** |
||
186 | * @param string $description |
||
187 | * |
||
188 | * @return Storage |
||
189 | */ |
||
190 | 1 | public function setDescription($description) |
|
196 | |||
197 | /** |
||
198 | * @return string |
||
199 | */ |
||
200 | 1 | public function getDescription() |
|
204 | |||
205 | /** |
||
206 | * @param string $path |
||
207 | * |
||
208 | * @return Storage |
||
209 | */ |
||
210 | 12 | public function setPath($path) |
|
219 | |||
220 | /** |
||
221 | * @return string |
||
222 | */ |
||
223 | 5 | public function getPath() |
|
227 | |||
228 | /** |
||
229 | * @return array |
||
230 | */ |
||
231 | 1 | public function getOldPaths() |
|
235 | |||
236 | /** |
||
237 | * @param Item $item |
||
238 | * |
||
239 | * @return Storage |
||
240 | */ |
||
241 | 1 | View Code Duplication | public function addItem(Item $item) |
250 | |||
251 | /** |
||
252 | * @param Item $item |
||
253 | * |
||
254 | * @return Storage |
||
255 | */ |
||
256 | 1 | View Code Duplication | public function removeItem(Item $item) |
265 | |||
266 | /** |
||
267 | * @return ArrayCollection |
||
268 | */ |
||
269 | 1 | public function getItems() |
|
273 | |||
274 | /** |
||
275 | * @param string $type |
||
276 | * |
||
277 | * @return Storage |
||
278 | */ |
||
279 | 31 | public function setType($type) |
|
285 | |||
286 | /** |
||
287 | * @return string |
||
288 | */ |
||
289 | 26 | public function getType() |
|
293 | |||
294 | /** |
||
295 | * @return array |
||
296 | */ |
||
297 | 1 | public static function getTypes() |
|
301 | |||
302 | /** |
||
303 | * @return array |
||
304 | */ |
||
305 | 5 | public static function getTypeTitles() |
|
309 | |||
310 | /** |
||
311 | * Get title for current type. |
||
312 | * |
||
313 | * @return string |
||
314 | */ |
||
315 | 5 | public function getTypeTitle() |
|
319 | |||
320 | /** |
||
321 | * Get types storage allow write. |
||
322 | * |
||
323 | * @return array |
||
324 | */ |
||
325 | 21 | public static function getTypesWritable() |
|
329 | |||
330 | /** |
||
331 | * Get types storage allow read. |
||
332 | * |
||
333 | * @return array |
||
334 | */ |
||
335 | 6 | public static function getTypesReadable() |
|
339 | |||
340 | /** |
||
341 | * Is path required to fill for current type of storage. |
||
342 | * |
||
343 | * @return bool |
||
344 | */ |
||
345 | 15 | public function isPathRequired() |
|
349 | |||
350 | /** |
||
351 | * @return bool |
||
352 | */ |
||
353 | 20 | public function isWritable() |
|
357 | |||
358 | /** |
||
359 | * @return bool |
||
360 | */ |
||
361 | 5 | public function isReadable() |
|
365 | |||
366 | /** |
||
367 | * Is valid path for current type. |
||
368 | * |
||
369 | * @param ExecutionContextInterface $context |
||
370 | */ |
||
371 | 10 | public function isPathValid(ExecutionContextInterface $context) |
|
377 | |||
378 | /** |
||
379 | * @param \DateTime $date_update |
||
380 | * |
||
381 | * @return Storage |
||
382 | */ |
||
383 | 2 | public function setDateUpdate(\DateTime $date_update) |
|
389 | |||
390 | /** |
||
391 | * @return \DateTime |
||
392 | */ |
||
393 | 2 | public function getDateUpdate() |
|
397 | |||
398 | /** |
||
399 | * @param \DateTime $file_modified |
||
400 | * |
||
401 | * @return Storage |
||
402 | */ |
||
403 | 1 | public function setFileModified(\DateTime $file_modified) |
|
409 | |||
410 | /** |
||
411 | * @return \DateTime |
||
412 | */ |
||
413 | 1 | public function getFileModified() |
|
417 | |||
418 | /** |
||
419 | * @ORM\PreUpdate |
||
420 | */ |
||
421 | 1 | public function doChangeDateUpdate() |
|
425 | |||
426 | /** |
||
427 | * @return string |
||
428 | */ |
||
429 | 1 | public function __toString() |
|
433 | } |
||
434 |
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.