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 TypedCollection 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 TypedCollection, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
8 | class TypedCollection extends Collection implements TypedCollectionInterface |
||
9 | { |
||
10 | private $type; |
||
11 | |||
12 | /** |
||
13 | * Constructor |
||
14 | * |
||
15 | * @param string $type The class every element must respect |
||
16 | * @param array $values |
||
17 | */ |
||
18 | 63 | public function __construct($type, array $values) |
|
26 | |||
27 | /** |
||
28 | * {@inheritdoc} |
||
29 | */ |
||
30 | 57 | public function getType() |
|
34 | |||
35 | /** |
||
36 | * {@inheritdoc} |
||
37 | */ |
||
38 | 1 | public function filter(callable $filter = null) |
|
45 | |||
46 | /** |
||
47 | * {@inheritdoc} |
||
48 | */ |
||
49 | 3 | public function intersect(CollectionInterface $collection) |
|
58 | |||
59 | /** |
||
60 | * {@inheritdoc} |
||
61 | */ |
||
62 | 2 | public function chunk($size) |
|
76 | |||
77 | /** |
||
78 | * {@inheritdoc} |
||
79 | */ |
||
80 | 1 | public function shift() |
|
87 | |||
88 | /** |
||
89 | * {@inheritdoc} |
||
90 | */ |
||
91 | 1 | public function uintersect(CollectionInterface $collection, callable $intersecter) |
|
100 | |||
101 | /** |
||
102 | * {@inheritdoc} |
||
103 | */ |
||
104 | 2 | public function keyIntersect(CollectionInterface $collection) |
|
113 | |||
114 | /** |
||
115 | * {@inheritdoc} |
||
116 | */ |
||
117 | 1 | public function map(callable $mapper) |
|
124 | |||
125 | /** |
||
126 | * {@inheritdoc} |
||
127 | */ |
||
128 | 2 | View Code Duplication | public function pad($size, $value) |
137 | |||
138 | /** |
||
139 | * {@inheritdoc} |
||
140 | */ |
||
141 | 1 | public function pop() |
|
148 | |||
149 | /** |
||
150 | * {@inheritdoc} |
||
151 | */ |
||
152 | 2 | public function diff(CollectionInterface $collection) |
|
161 | |||
162 | /** |
||
163 | * {@inheritdoc} |
||
164 | */ |
||
165 | 2 | View Code Duplication | public function push($value) |
174 | |||
175 | /** |
||
176 | * {@inheritdoc} |
||
177 | */ |
||
178 | 2 | public function rand($num = 1) |
|
185 | |||
186 | /** |
||
187 | * {@inheritdoc} |
||
188 | */ |
||
189 | 2 | public function merge(CollectionInterface $collection) |
|
198 | |||
199 | /** |
||
200 | * {@inheritdoc} |
||
201 | */ |
||
202 | 1 | public function slice($offset, $length = null, $preserveKeys = false) |
|
209 | |||
210 | /** |
||
211 | * {@inheritdoc} |
||
212 | */ |
||
213 | 2 | public function udiff(CollectionInterface $collection, callable $differ) |
|
222 | |||
223 | /** |
||
224 | * {@inheritdoc} |
||
225 | */ |
||
226 | 1 | public function splice($offset, $length = 0, $replacement = []) |
|
233 | |||
234 | /** |
||
235 | * {@inheritdoc} |
||
236 | */ |
||
237 | 1 | public function unique($flags = SORT_REGULAR) |
|
244 | |||
245 | /** |
||
246 | * {@inheritdoc} |
||
247 | */ |
||
248 | 1 | public function values() |
|
255 | |||
256 | /** |
||
257 | * {@inheritdoc} |
||
258 | */ |
||
259 | 2 | public function replace(CollectionInterface $collection) |
|
268 | |||
269 | /** |
||
270 | * {@inheritdoc} |
||
271 | */ |
||
272 | 1 | public function reverse($preserveKeys = false) |
|
279 | |||
280 | /** |
||
281 | * {@inheritdoc} |
||
282 | */ |
||
283 | 2 | View Code Duplication | public function unshift($value) |
292 | |||
293 | /** |
||
294 | * {@inheritdoc} |
||
295 | */ |
||
296 | 2 | public function keyDiff(CollectionInterface $collection) |
|
305 | |||
306 | /** |
||
307 | * {@inheritdoc} |
||
308 | */ |
||
309 | 2 | public function ukeyDiff(CollectionInterface $collection, callable $differ) |
|
318 | |||
319 | /** |
||
320 | * {@inheritdoc} |
||
321 | */ |
||
322 | 2 | public function associativeDiff(CollectionInterface $collection) |
|
331 | |||
332 | /** |
||
333 | * {@inheritdoc} |
||
334 | */ |
||
335 | 2 | public function ukeyIntersect(CollectionInterface $collection, callable $intersecter) |
|
344 | |||
345 | /** |
||
346 | * {@inheritdoc} |
||
347 | */ |
||
348 | 2 | public function associativeIntersect(CollectionInterface $collection) |
|
357 | |||
358 | /** |
||
359 | * {@inheritdoc} |
||
360 | */ |
||
361 | 1 | public function sort($flags = SORT_REGULAR) |
|
368 | |||
369 | /** |
||
370 | * {@inheritdoc} |
||
371 | */ |
||
372 | 1 | public function associativeSort($flags = SORT_REGULAR) |
|
379 | |||
380 | /** |
||
381 | * {@inheritdoc} |
||
382 | */ |
||
383 | 1 | public function keySort($flags = SORT_REGULAR) |
|
390 | |||
391 | /** |
||
392 | * {@inheritdoc} |
||
393 | */ |
||
394 | 1 | public function ukeySort(callable $sorter) |
|
401 | |||
402 | /** |
||
403 | * {@inheritdoc} |
||
404 | */ |
||
405 | 1 | public function reverseSort($flags = SORT_REGULAR) |
|
412 | |||
413 | /** |
||
414 | * {@inheritdoc} |
||
415 | */ |
||
416 | 1 | public function usort(callable $sorter) |
|
423 | |||
424 | /** |
||
425 | * {@inheritdoc} |
||
426 | */ |
||
427 | 1 | public function associativeReverseSort($flags = SORT_REGULAR) |
|
434 | |||
435 | /** |
||
436 | * {@inheritdoc} |
||
437 | */ |
||
438 | 1 | public function keyReverseSort($flags = SORT_REGULAR) |
|
445 | |||
446 | /** |
||
447 | * {@inheritdoc} |
||
448 | */ |
||
449 | 1 | public function uassociativeSort(callable $sorter) |
|
456 | |||
457 | /** |
||
458 | * {@inheritdoc} |
||
459 | */ |
||
460 | 1 | public function naturalSort() |
|
467 | |||
468 | /** |
||
469 | * {@inheritdoc} |
||
470 | */ |
||
471 | 1 | public function shuffle() |
|
478 | |||
479 | /** |
||
480 | * {@inheritdoc} |
||
481 | */ |
||
482 | 1 | public function take($size, $preserveKeys = false) |
|
489 | |||
490 | /** |
||
491 | * {@inheritdoc} |
||
492 | */ |
||
493 | 1 | public function grep($pattern, $revert = false) |
|
500 | |||
501 | /** |
||
502 | * Check if every element respect the given type |
||
503 | * |
||
504 | * @throws InvalidArgumentException If a value doesn't respect the type |
||
505 | * |
||
506 | * @param string $type |
||
507 | * @param array $values |
||
508 | * |
||
509 | * @return void |
||
510 | */ |
||
511 | 63 | protected function validate($type, array $values) |
|
522 | |||
523 | /** |
||
524 | * Check if the given collection is compatible with the current one |
||
525 | * |
||
526 | * @throws BadMethodCallException If the collection is not compatible |
||
527 | * |
||
528 | * @param CollectionInterface $collection |
||
529 | * |
||
530 | * @return void |
||
531 | */ |
||
532 | 24 | private function validateCollection(CollectionInterface $collection) |
|
543 | } |
||
544 |
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.