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 Place 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 Place, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
20 | class Place |
||
21 | { |
||
22 | /** |
||
23 | * @var string|null |
||
24 | */ |
||
25 | private $id; |
||
26 | |||
27 | /** |
||
28 | * @var string|null |
||
29 | */ |
||
30 | private $placeId; |
||
31 | |||
32 | /** |
||
33 | * @var string|null |
||
34 | */ |
||
35 | private $name; |
||
36 | |||
37 | /** |
||
38 | * @var string|null |
||
39 | */ |
||
40 | private $formattedAddress; |
||
41 | |||
42 | /** |
||
43 | * @var string|null |
||
44 | */ |
||
45 | private $formattedPhoneNumber; |
||
46 | |||
47 | /** |
||
48 | * @var string|null |
||
49 | */ |
||
50 | private $internationalPhoneNumber; |
||
51 | |||
52 | /** |
||
53 | * @var string|null |
||
54 | */ |
||
55 | private $url; |
||
56 | |||
57 | /** |
||
58 | * @var string|null |
||
59 | */ |
||
60 | private $icon; |
||
61 | |||
62 | /** |
||
63 | * @var string|null |
||
64 | */ |
||
65 | private $scope; |
||
66 | |||
67 | /** |
||
68 | * @var int|null |
||
69 | */ |
||
70 | private $priceLevel; |
||
71 | |||
72 | /** |
||
73 | * @var float|null |
||
74 | */ |
||
75 | private $rating; |
||
76 | |||
77 | /** |
||
78 | * @var int|null |
||
79 | */ |
||
80 | private $utcOffset; |
||
81 | |||
82 | /** |
||
83 | * @var string|null |
||
84 | */ |
||
85 | private $vicinity; |
||
86 | |||
87 | /** |
||
88 | * @var string|null |
||
89 | */ |
||
90 | private $website; |
||
91 | |||
92 | /** |
||
93 | * @var Geometry|null |
||
94 | */ |
||
95 | private $geometry; |
||
96 | |||
97 | /** |
||
98 | * @var OpeningHours|null |
||
99 | */ |
||
100 | private $openingHours; |
||
101 | |||
102 | /** |
||
103 | * @var AddressComponent[] |
||
104 | */ |
||
105 | private $addressComponents = []; |
||
106 | |||
107 | /** |
||
108 | * @var Photo[] |
||
109 | */ |
||
110 | private $photos = []; |
||
111 | |||
112 | /** |
||
113 | * @var AlternatePlaceId[] |
||
114 | */ |
||
115 | private $alternatePlaceIds = []; |
||
116 | |||
117 | /** |
||
118 | * @var Review[] |
||
119 | */ |
||
120 | private $reviews = []; |
||
121 | |||
122 | /** |
||
123 | * @var string[] |
||
124 | */ |
||
125 | private $types = []; |
||
126 | |||
127 | /** |
||
128 | * @var bool|null |
||
129 | */ |
||
130 | private $permanentlyClose; |
||
131 | |||
132 | /** |
||
133 | * @return bool |
||
134 | */ |
||
135 | 8 | public function hasId() |
|
139 | |||
140 | /** |
||
141 | * @return string|null |
||
142 | */ |
||
143 | 8 | public function getId() |
|
147 | |||
148 | /** |
||
149 | * @param string|null $id |
||
150 | */ |
||
151 | 4 | public function setId($id) |
|
155 | |||
156 | /** |
||
157 | * @return bool |
||
158 | */ |
||
159 | 8 | public function hasPlaceId() |
|
163 | |||
164 | /** |
||
165 | * @return string|null |
||
166 | */ |
||
167 | 8 | public function getPlaceId() |
|
171 | |||
172 | /** |
||
173 | * @param string|null $placeId |
||
174 | */ |
||
175 | 4 | public function setPlaceId($placeId) |
|
179 | |||
180 | /** |
||
181 | * @return bool |
||
182 | */ |
||
183 | 8 | public function hasName() |
|
187 | |||
188 | /** |
||
189 | * @return string|null |
||
190 | */ |
||
191 | 8 | public function getName() |
|
195 | |||
196 | /** |
||
197 | * @param string|null $name |
||
198 | */ |
||
199 | 4 | public function setName($name) |
|
203 | |||
204 | /** |
||
205 | * @return bool |
||
206 | */ |
||
207 | 8 | public function hasFormattedAddress() |
|
211 | |||
212 | /** |
||
213 | * @return string|null |
||
214 | */ |
||
215 | 8 | public function getFormattedAddress() |
|
219 | |||
220 | /** |
||
221 | * @param string|null $formattedAddress |
||
222 | */ |
||
223 | 4 | public function setFormattedAddress($formattedAddress) |
|
227 | |||
228 | /** |
||
229 | * @return bool |
||
230 | */ |
||
231 | 8 | public function hasFormattedPhoneNumber() |
|
235 | |||
236 | /** |
||
237 | * @return string|null |
||
238 | */ |
||
239 | 8 | public function getFormattedPhoneNumber() |
|
243 | |||
244 | /** |
||
245 | * @param string|null $formattedPhoneNumber |
||
246 | */ |
||
247 | 4 | public function setFormattedPhoneNumber($formattedPhoneNumber) |
|
251 | |||
252 | /** |
||
253 | * @return bool |
||
254 | */ |
||
255 | 8 | public function hasInternationalPhoneNumber() |
|
259 | |||
260 | /** |
||
261 | * @return string|null |
||
262 | */ |
||
263 | 8 | public function getInternationalPhoneNumber() |
|
267 | |||
268 | /** |
||
269 | * @param string|null $internationalPhoneNumber |
||
270 | */ |
||
271 | 4 | public function setInternationalPhoneNumber($internationalPhoneNumber) |
|
275 | |||
276 | /** |
||
277 | * @return bool |
||
278 | */ |
||
279 | 8 | public function hasUrl() |
|
283 | |||
284 | /** |
||
285 | * @return string|null |
||
286 | */ |
||
287 | 8 | public function getUrl() |
|
291 | |||
292 | /** |
||
293 | * @param string|null $url |
||
294 | */ |
||
295 | 4 | public function setUrl($url) |
|
299 | |||
300 | /** |
||
301 | * @return bool |
||
302 | */ |
||
303 | 8 | public function hasIcon() |
|
307 | |||
308 | /** |
||
309 | * @return string|null |
||
310 | */ |
||
311 | 8 | public function getIcon() |
|
315 | |||
316 | /** |
||
317 | * @param string|null $icon |
||
318 | */ |
||
319 | 4 | public function setIcon($icon) |
|
323 | |||
324 | /** |
||
325 | * @return bool |
||
326 | */ |
||
327 | 8 | public function hasScope() |
|
331 | |||
332 | /** |
||
333 | * @return string|null |
||
334 | */ |
||
335 | 8 | public function getScope() |
|
339 | |||
340 | /** |
||
341 | * @param string|null $scope |
||
342 | */ |
||
343 | 4 | public function setScope($scope) |
|
347 | |||
348 | /** |
||
349 | * @return bool |
||
350 | */ |
||
351 | 8 | public function hasPriceLevel() |
|
355 | |||
356 | /** |
||
357 | * @return int|null |
||
358 | */ |
||
359 | 8 | public function getPriceLevel() |
|
363 | |||
364 | /** |
||
365 | * @param int|null $priceLevel |
||
366 | */ |
||
367 | 4 | public function setPriceLevel($priceLevel) |
|
371 | |||
372 | /** |
||
373 | * @return bool |
||
374 | */ |
||
375 | 8 | public function hasRating() |
|
379 | |||
380 | /** |
||
381 | * @return float|null |
||
382 | */ |
||
383 | 8 | public function getRating() |
|
387 | |||
388 | /** |
||
389 | * @param float|null $rating |
||
390 | */ |
||
391 | 4 | public function setRating($rating) |
|
395 | |||
396 | /** |
||
397 | * @return bool |
||
398 | */ |
||
399 | 8 | public function hasUtcOffset() |
|
403 | |||
404 | /** |
||
405 | * @return int|null |
||
406 | */ |
||
407 | 8 | public function getUtcOffset() |
|
411 | |||
412 | /** |
||
413 | * @param int|null $utcOffset |
||
414 | */ |
||
415 | 4 | public function setUtcOffset($utcOffset) |
|
419 | |||
420 | /** |
||
421 | * @return bool |
||
422 | */ |
||
423 | 8 | public function hasVicinity() |
|
427 | |||
428 | /** |
||
429 | * @return string|null |
||
430 | */ |
||
431 | 8 | public function getVicinity() |
|
435 | |||
436 | /** |
||
437 | * @param string|null $vicinity |
||
438 | */ |
||
439 | 4 | public function setVicinity($vicinity) |
|
443 | |||
444 | /** |
||
445 | * @return bool |
||
446 | */ |
||
447 | 8 | public function hasWebsite() |
|
451 | |||
452 | /** |
||
453 | * @return string|null |
||
454 | */ |
||
455 | 8 | public function getWebsite() |
|
459 | |||
460 | /** |
||
461 | * @param string|null $website |
||
462 | */ |
||
463 | 4 | public function setWebsite($website) |
|
467 | |||
468 | /** |
||
469 | * @return bool |
||
470 | */ |
||
471 | 8 | public function hasGeometry() |
|
475 | |||
476 | /** |
||
477 | * @return Geometry|null |
||
478 | */ |
||
479 | 8 | public function getGeometry() |
|
483 | |||
484 | 4 | public function setGeometry(Geometry $geometry = null) |
|
488 | |||
489 | /** |
||
490 | * @return bool |
||
491 | */ |
||
492 | 8 | public function hasOpeningHours() |
|
496 | |||
497 | /** |
||
498 | * @return OpeningHours|null |
||
499 | */ |
||
500 | 8 | public function getOpeningHours() |
|
504 | |||
505 | 4 | public function setOpeningHours(OpeningHours $openingHours = null) |
|
509 | |||
510 | /** |
||
511 | * @param string|null $type |
||
512 | * |
||
513 | * @return bool |
||
514 | */ |
||
515 | 24 | public function hasAddressComponents($type = null) |
|
521 | |||
522 | /** |
||
523 | * @param string|null $type |
||
524 | * |
||
525 | * @return AddressComponent[] |
||
526 | */ |
||
527 | 24 | View Code Duplication | public function getAddressComponents($type = null) |
543 | |||
544 | /** |
||
545 | * @param AddressComponent[] $addressComponents |
||
546 | */ |
||
547 | 12 | public function setAddressComponents(array $addressComponents) |
|
552 | |||
553 | /** |
||
554 | * @param AddressComponent[] $addressComponents |
||
555 | */ |
||
556 | 12 | public function addAddressComponents(array $addressComponents) |
|
562 | |||
563 | /** |
||
564 | * @return bool |
||
565 | */ |
||
566 | 20 | public function hasAddressComponent(AddressComponent $addressComponent) |
|
570 | |||
571 | 20 | public function addAddressComponent(AddressComponent $addressComponent) |
|
577 | |||
578 | 4 | public function removeAddressComponent(AddressComponent $addressComponent) |
|
583 | |||
584 | /** |
||
585 | * @return bool |
||
586 | */ |
||
587 | 20 | public function hasPhotos() |
|
591 | |||
592 | /** |
||
593 | * @return Photo[] |
||
594 | */ |
||
595 | 20 | public function getPhotos() |
|
599 | |||
600 | /** |
||
601 | * @param Photo[] $photos |
||
602 | */ |
||
603 | 8 | public function setPhotos(array $photos) |
|
608 | |||
609 | /** |
||
610 | * @param Photo[] $photos |
||
611 | */ |
||
612 | 8 | public function addPhotos(array $photos) |
|
618 | |||
619 | /** |
||
620 | * @return bool |
||
621 | */ |
||
622 | 16 | public function hasPhoto(Photo $photo) |
|
626 | |||
627 | 16 | public function addPhoto(Photo $photo) |
|
633 | |||
634 | 4 | public function removePhoto(Photo $photo) |
|
639 | |||
640 | /** |
||
641 | * @return bool |
||
642 | */ |
||
643 | 20 | public function hasAlternatePlaceIds() |
|
647 | |||
648 | /** |
||
649 | * @return AlternatePlaceId[] |
||
650 | */ |
||
651 | 20 | public function getAlternatePlaceIds() |
|
655 | |||
656 | /** |
||
657 | * @param AlternatePlaceId[] $alternatePlaceIds |
||
658 | */ |
||
659 | 8 | public function setAlternatePlaceIds(array $alternatePlaceIds) |
|
664 | |||
665 | /** |
||
666 | * @param AlternatePlaceId[] $alternatePlaceIds |
||
667 | */ |
||
668 | 8 | public function addAlternatePlaceIds(array $alternatePlaceIds) |
|
674 | |||
675 | /** |
||
676 | * @return bool |
||
677 | */ |
||
678 | 16 | public function hasAlternatePlaceId(AlternatePlaceId $alternatePlaceId) |
|
682 | |||
683 | 16 | public function addAlternatePlaceId(AlternatePlaceId $alternatePlaceId) |
|
689 | |||
690 | 4 | public function removeAlternatePlaceId(AlternatePlaceId $alternatePlaceId) |
|
695 | |||
696 | /** |
||
697 | * @return bool |
||
698 | */ |
||
699 | 20 | public function hasReviews() |
|
703 | |||
704 | /** |
||
705 | * @return Review[] |
||
706 | */ |
||
707 | 20 | public function getReviews() |
|
711 | |||
712 | /** |
||
713 | * @param Review[] $reviews |
||
714 | */ |
||
715 | 8 | public function setReviews(array $reviews) |
|
720 | |||
721 | /** |
||
722 | * @param Review[] $reviews |
||
723 | */ |
||
724 | 8 | public function addReviews(array $reviews) |
|
730 | |||
731 | /** |
||
732 | * @return bool |
||
733 | */ |
||
734 | 16 | public function hasReview(Review $review) |
|
738 | |||
739 | 16 | public function addReview(Review $review) |
|
745 | |||
746 | 4 | public function removeReview(Review $review) |
|
751 | |||
752 | /** |
||
753 | * @return bool |
||
754 | */ |
||
755 | 20 | public function hasTypes() |
|
759 | |||
760 | /** |
||
761 | * @return string[] |
||
762 | */ |
||
763 | 20 | public function getTypes() |
|
767 | |||
768 | /** |
||
769 | * @param string[] $types |
||
770 | */ |
||
771 | 8 | public function setTypes(array $types) |
|
776 | |||
777 | /** |
||
778 | * @param string[] $types |
||
779 | */ |
||
780 | 8 | public function addTypes(array $types) |
|
786 | |||
787 | /** |
||
788 | * @param string $type |
||
789 | * |
||
790 | * @return bool |
||
791 | */ |
||
792 | 16 | public function hasType($type) |
|
796 | |||
797 | /** |
||
798 | * @param string $type |
||
799 | */ |
||
800 | 16 | public function addType($type) |
|
806 | |||
807 | /** |
||
808 | * @param string $type |
||
809 | */ |
||
810 | 4 | public function removeType($type) |
|
815 | |||
816 | /** |
||
817 | * @return bool |
||
818 | */ |
||
819 | 8 | public function hasPermanentlyClose() |
|
823 | |||
824 | /** |
||
825 | * @return bool|null |
||
826 | */ |
||
827 | 8 | public function isPermanentlyClose() |
|
831 | |||
832 | /** |
||
833 | * @param bool|null $permanentlyClose |
||
834 | */ |
||
835 | 4 | public function setPermanentlyClose($permanentlyClose) |
|
839 | } |
||
840 |
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.