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 Product 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 Product, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
28 | class Product extends \Eccube\Entity\AbstractEntity |
||
29 | { |
||
30 | private $_calc = false; |
||
31 | private $stockFinds = []; |
||
32 | private $stocks = []; |
||
33 | private $stockUnlimiteds = []; |
||
34 | private $price01 = []; |
||
35 | private $price02 = []; |
||
36 | private $price01IncTaxs = []; |
||
37 | private $price02IncTaxs = []; |
||
38 | private $codes = []; |
||
39 | private $classCategories1 = []; |
||
40 | private $classCategories2 = []; |
||
41 | private $className1; |
||
42 | private $className2; |
||
43 | |||
44 | /** |
||
45 | * @return string |
||
46 | */ |
||
47 | public function __toString() |
||
48 | { |
||
49 | return (string) $this->getName(); |
||
50 | } |
||
51 | |||
52 | 48 | public function _calc() |
|
118 | |||
119 | /** |
||
120 | * Is Enable |
||
121 | * |
||
122 | * @return bool |
||
123 | */ |
||
124 | 80 | public function isEnable() |
|
128 | |||
129 | /** |
||
130 | * Get ClassName1 |
||
131 | * |
||
132 | * @return string |
||
133 | */ |
||
134 | 45 | public function getClassName1() |
|
140 | |||
141 | /** |
||
142 | * Get ClassName2 |
||
143 | * |
||
144 | * @return string |
||
145 | */ |
||
146 | 45 | public function getClassName2() |
|
152 | |||
153 | /** |
||
154 | * Get getClassCategories1 |
||
155 | * |
||
156 | * @return array |
||
157 | */ |
||
158 | 45 | public function getClassCategories1() |
|
164 | |||
165 | 45 | public function getClassCategories1AsFlip() |
|
169 | |||
170 | /** |
||
171 | * Get getClassCategories2 |
||
172 | * |
||
173 | * @return array |
||
174 | */ |
||
175 | 4 | public function getClassCategories2($class_category1) |
|
181 | |||
182 | 4 | public function getClassCategories2AsFlip($class_category1) |
|
186 | |||
187 | /** |
||
188 | * Get StockFind |
||
189 | * |
||
190 | * @return bool |
||
191 | */ |
||
192 | 46 | public function getStockFind() |
|
198 | |||
199 | /** |
||
200 | * Get Stock min |
||
201 | * |
||
202 | * @return integer |
||
203 | */ |
||
204 | public function getStockMin() |
||
210 | |||
211 | /** |
||
212 | * Get Stock max |
||
213 | * |
||
214 | * @return integer |
||
215 | */ |
||
216 | public function getStockMax() |
||
222 | |||
223 | /** |
||
224 | * Get StockUnlimited min |
||
225 | * |
||
226 | * @return integer |
||
227 | */ |
||
228 | public function getStockUnlimitedMin() |
||
234 | |||
235 | /** |
||
236 | * Get StockUnlimited max |
||
237 | * |
||
238 | * @return integer |
||
239 | */ |
||
240 | public function getStockUnlimitedMax() |
||
246 | |||
247 | /** |
||
248 | * Get Price01 min |
||
249 | * |
||
250 | * @return integer |
||
251 | */ |
||
252 | 11 | View Code Duplication | public function getPrice01Min() |
262 | |||
263 | /** |
||
264 | * Get Price01 max |
||
265 | * |
||
266 | * @return integer |
||
267 | */ |
||
268 | 2 | View Code Duplication | public function getPrice01Max() |
278 | |||
279 | /** |
||
280 | * Get Price02 min |
||
281 | * |
||
282 | * @return integer |
||
283 | */ |
||
284 | 3 | public function getPrice02Min() |
|
290 | |||
291 | /** |
||
292 | * Get Price02 max |
||
293 | * |
||
294 | * @return integer |
||
295 | */ |
||
296 | 3 | public function getPrice02Max() |
|
302 | |||
303 | /** |
||
304 | * Get Price01IncTax min |
||
305 | * |
||
306 | * @return integer |
||
307 | */ |
||
308 | 2 | public function getPrice01IncTaxMin() |
|
314 | |||
315 | /** |
||
316 | * Get Price01IncTax max |
||
317 | * |
||
318 | * @return integer |
||
319 | */ |
||
320 | 2 | public function getPrice01IncTaxMax() |
|
326 | |||
327 | /** |
||
328 | * Get Price02IncTax min |
||
329 | * |
||
330 | * @return integer |
||
331 | */ |
||
332 | 14 | public function getPrice02IncTaxMin() |
|
338 | |||
339 | /** |
||
340 | * Get Price02IncTax max |
||
341 | * |
||
342 | * @return integer |
||
343 | */ |
||
344 | 14 | public function getPrice02IncTaxMax() |
|
350 | |||
351 | /** |
||
352 | * Get Product_code min |
||
353 | * |
||
354 | * @return integer |
||
355 | */ |
||
356 | 13 | View Code Duplication | public function getCodeMin() |
369 | |||
370 | /** |
||
371 | * Get Product_code max |
||
372 | * |
||
373 | * @return integer |
||
374 | */ |
||
375 | 13 | View Code Duplication | public function getCodeMax() |
388 | |||
389 | 62 | public function getMainListImage() |
|
395 | |||
396 | 1 | public function getMainFileName() |
|
404 | |||
405 | 43 | public function hasProductClass() |
|
418 | |||
419 | /** |
||
420 | * @var integer |
||
421 | * |
||
422 | * @ORM\Column(name="id", type="integer", options={"unsigned":true}) |
||
423 | * @ORM\Id |
||
424 | * @ORM\GeneratedValue(strategy="IDENTITY") |
||
425 | */ |
||
426 | private $id; |
||
427 | |||
428 | /** |
||
429 | * @var string |
||
430 | * |
||
431 | * @ORM\Column(name="name", type="string", length=255) |
||
432 | */ |
||
433 | private $name; |
||
434 | |||
435 | /** |
||
436 | * @var string|null |
||
437 | * |
||
438 | * @ORM\Column(name="note", type="string", length=4000, nullable=true) |
||
439 | */ |
||
440 | private $note; |
||
441 | |||
442 | /** |
||
443 | * @var string|null |
||
444 | * |
||
445 | * @ORM\Column(name="description_list", type="string", length=4000, nullable=true) |
||
446 | */ |
||
447 | private $description_list; |
||
448 | |||
449 | /** |
||
450 | * @var string|null |
||
451 | * |
||
452 | * @ORM\Column(name="description_detail", type="string", length=4000, nullable=true) |
||
453 | */ |
||
454 | private $description_detail; |
||
455 | |||
456 | /** |
||
457 | * @var string|null |
||
458 | * |
||
459 | * @ORM\Column(name="search_word", type="string", length=4000, nullable=true) |
||
460 | */ |
||
461 | private $search_word; |
||
462 | |||
463 | /** |
||
464 | * @var string|null |
||
465 | * |
||
466 | * @ORM\Column(name="free_area", type="text", nullable=true) |
||
467 | */ |
||
468 | private $free_area; |
||
469 | |||
470 | /** |
||
471 | * @var \DateTime |
||
472 | * |
||
473 | * @ORM\Column(name="create_date", type="datetimetz") |
||
474 | */ |
||
475 | private $create_date; |
||
476 | |||
477 | /** |
||
478 | * @var \DateTime |
||
479 | * |
||
480 | * @ORM\Column(name="update_date", type="datetimetz") |
||
481 | */ |
||
482 | private $update_date; |
||
483 | |||
484 | /** |
||
485 | * @var \Doctrine\Common\Collections\Collection |
||
486 | * |
||
487 | * @ORM\OneToMany(targetEntity="Eccube\Entity\ProductCategory", mappedBy="Product", cascade={"persist","remove"}) |
||
488 | */ |
||
489 | private $ProductCategories; |
||
490 | |||
491 | /** |
||
492 | * @var \Doctrine\Common\Collections\Collection |
||
493 | * |
||
494 | * @ORM\OneToMany(targetEntity="Eccube\Entity\ProductClass", mappedBy="Product", cascade={"persist","remove"}) |
||
495 | */ |
||
496 | private $ProductClasses; |
||
497 | |||
498 | /** |
||
499 | * @var \Doctrine\Common\Collections\Collection |
||
500 | * |
||
501 | * @ORM\OneToMany(targetEntity="Eccube\Entity\ProductImage", mappedBy="Product", cascade={"remove"}) |
||
502 | * @ORM\OrderBy({ |
||
503 | * "sort_no"="ASC" |
||
504 | * }) |
||
505 | */ |
||
506 | private $ProductImage; |
||
507 | |||
508 | /** |
||
509 | * @var \Doctrine\Common\Collections\Collection |
||
510 | * |
||
511 | * @ORM\OneToMany(targetEntity="Eccube\Entity\ProductTag", mappedBy="Product") |
||
512 | */ |
||
513 | private $ProductTag; |
||
514 | |||
515 | /** |
||
516 | * @var \Doctrine\Common\Collections\Collection |
||
517 | * |
||
518 | * @ORM\OneToMany(targetEntity="Eccube\Entity\CustomerFavoriteProduct", mappedBy="Product") |
||
519 | */ |
||
520 | private $CustomerFavoriteProducts; |
||
521 | |||
522 | /** |
||
523 | * @var \Eccube\Entity\Member |
||
524 | * |
||
525 | * @ORM\ManyToOne(targetEntity="Eccube\Entity\Member") |
||
526 | * @ORM\JoinColumns({ |
||
527 | * @ORM\JoinColumn(name="creator_id", referencedColumnName="id") |
||
528 | * }) |
||
529 | */ |
||
530 | private $Creator; |
||
531 | |||
532 | /** |
||
533 | * @var \Eccube\Entity\Master\ProductStatus |
||
534 | * |
||
535 | * @ORM\ManyToOne(targetEntity="Eccube\Entity\Master\ProductStatus") |
||
536 | * @ORM\JoinColumns({ |
||
537 | * @ORM\JoinColumn(name="product_status_id", referencedColumnName="id") |
||
538 | * }) |
||
539 | */ |
||
540 | private $Status; |
||
541 | |||
542 | /** |
||
543 | * Constructor |
||
544 | */ |
||
545 | 367 | public function __construct() |
|
553 | |||
554 | 1 | public function __clone() |
|
558 | |||
559 | 1 | public function copy() |
|
598 | |||
599 | /** |
||
600 | * Get id. |
||
601 | * |
||
602 | * @return int |
||
603 | */ |
||
604 | 376 | public function getId() |
|
608 | |||
609 | /** |
||
610 | * Set name. |
||
611 | * |
||
612 | * @param string $name |
||
613 | * |
||
614 | * @return Product |
||
615 | */ |
||
616 | 367 | public function setName($name) |
|
622 | |||
623 | /** |
||
624 | * Get name. |
||
625 | * |
||
626 | * @return string |
||
627 | */ |
||
628 | 282 | public function getName() |
|
632 | |||
633 | /** |
||
634 | * Set note. |
||
635 | * |
||
636 | * @param string|null $note |
||
637 | * |
||
638 | * @return Product |
||
639 | */ |
||
640 | 25 | public function setNote($note = null) |
|
646 | |||
647 | /** |
||
648 | * Get note. |
||
649 | * |
||
650 | * @return string|null |
||
651 | */ |
||
652 | 18 | public function getNote() |
|
656 | |||
657 | /** |
||
658 | * Set descriptionList. |
||
659 | * |
||
660 | * @param string|null $descriptionList |
||
661 | * |
||
662 | * @return Product |
||
663 | */ |
||
664 | 364 | public function setDescriptionList($descriptionList = null) |
|
670 | |||
671 | /** |
||
672 | * Get descriptionList. |
||
673 | * |
||
674 | * @return string|null |
||
675 | */ |
||
676 | 20 | public function getDescriptionList() |
|
680 | |||
681 | /** |
||
682 | * Set descriptionDetail. |
||
683 | * |
||
684 | * @param string|null $descriptionDetail |
||
685 | * |
||
686 | * @return Product |
||
687 | */ |
||
688 | 364 | public function setDescriptionDetail($descriptionDetail = null) |
|
694 | |||
695 | /** |
||
696 | * Get descriptionDetail. |
||
697 | * |
||
698 | * @return string|null |
||
699 | */ |
||
700 | 29 | public function getDescriptionDetail() |
|
704 | |||
705 | /** |
||
706 | * Set searchWord. |
||
707 | * |
||
708 | * @param string|null $searchWord |
||
709 | * |
||
710 | * @return Product |
||
711 | */ |
||
712 | 23 | public function setSearchWord($searchWord = null) |
|
718 | |||
719 | /** |
||
720 | * Get searchWord. |
||
721 | * |
||
722 | * @return string|null |
||
723 | */ |
||
724 | 18 | public function getSearchWord() |
|
728 | |||
729 | /** |
||
730 | * Set freeArea. |
||
731 | * |
||
732 | * @param string|null $freeArea |
||
733 | * |
||
734 | * @return Product |
||
735 | */ |
||
736 | 25 | public function setFreeArea($freeArea = null) |
|
742 | |||
743 | /** |
||
744 | * Get freeArea. |
||
745 | * |
||
746 | * @return string|null |
||
747 | */ |
||
748 | 29 | public function getFreeArea() |
|
752 | |||
753 | /** |
||
754 | * Set createDate. |
||
755 | * |
||
756 | * @param \DateTime $createDate |
||
757 | * |
||
758 | * @return Product |
||
759 | */ |
||
760 | 366 | public function setCreateDate($createDate) |
|
766 | |||
767 | /** |
||
768 | * Get createDate. |
||
769 | * |
||
770 | * @return \DateTime |
||
771 | */ |
||
772 | 8 | public function getCreateDate() |
|
776 | |||
777 | /** |
||
778 | * Set updateDate. |
||
779 | * |
||
780 | * @param \DateTime $updateDate |
||
781 | * |
||
782 | * @return Product |
||
783 | */ |
||
784 | 367 | public function setUpdateDate($updateDate) |
|
790 | |||
791 | /** |
||
792 | * Get updateDate. |
||
793 | * |
||
794 | * @return \DateTime |
||
795 | */ |
||
796 | 7 | public function getUpdateDate() |
|
800 | |||
801 | /** |
||
802 | * Add productCategory. |
||
803 | * |
||
804 | * @param \Eccube\Entity\ProductCategory $productCategory |
||
805 | * |
||
806 | * @return Product |
||
807 | */ |
||
808 | 356 | public function addProductCategory(\Eccube\Entity\ProductCategory $productCategory) |
|
814 | |||
815 | /** |
||
816 | * Remove productCategory. |
||
817 | * |
||
818 | * @param \Eccube\Entity\ProductCategory $productCategory |
||
819 | * |
||
820 | * @return boolean TRUE if this collection contained the specified element, FALSE otherwise. |
||
821 | */ |
||
822 | 12 | public function removeProductCategory(\Eccube\Entity\ProductCategory $productCategory) |
|
826 | |||
827 | /** |
||
828 | * Get productCategories. |
||
829 | * |
||
830 | * @return \Doctrine\Common\Collections\Collection |
||
831 | */ |
||
832 | 38 | public function getProductCategories() |
|
836 | |||
837 | /** |
||
838 | * Add productClass. |
||
839 | * |
||
840 | * @param \Eccube\Entity\ProductClass $productClass |
||
841 | * |
||
842 | * @return Product |
||
843 | */ |
||
844 | 367 | public function addProductClass(\Eccube\Entity\ProductClass $productClass) |
|
850 | |||
851 | /** |
||
852 | * Remove productClass. |
||
853 | * |
||
854 | * @param \Eccube\Entity\ProductClass $productClass |
||
855 | * |
||
856 | * @return boolean TRUE if this collection contained the specified element, FALSE otherwise. |
||
857 | */ |
||
858 | public function removeProductClass(\Eccube\Entity\ProductClass $productClass) |
||
862 | |||
863 | /** |
||
864 | * Get productClasses. |
||
865 | * |
||
866 | * @return \Doctrine\Common\Collections\Collection |
||
867 | */ |
||
868 | 333 | public function getProductClasses() |
|
872 | |||
873 | /** |
||
874 | * Add productImage. |
||
875 | * |
||
876 | * @param \Eccube\Entity\ProductImage $productImage |
||
877 | * |
||
878 | * @return Product |
||
879 | */ |
||
880 | 356 | public function addProductImage(\Eccube\Entity\ProductImage $productImage) |
|
886 | |||
887 | /** |
||
888 | * Remove productImage. |
||
889 | * |
||
890 | * @param \Eccube\Entity\ProductImage $productImage |
||
891 | * |
||
892 | * @return boolean TRUE if this collection contained the specified element, FALSE otherwise. |
||
893 | */ |
||
894 | 2 | public function removeProductImage(\Eccube\Entity\ProductImage $productImage) |
|
898 | |||
899 | /** |
||
900 | * Get productImage. |
||
901 | * |
||
902 | * @return \Doctrine\Common\Collections\Collection |
||
903 | */ |
||
904 | 95 | public function getProductImage() |
|
908 | |||
909 | /** |
||
910 | * Add productTag. |
||
911 | * |
||
912 | * @param \Eccube\Entity\ProductTag $productTag |
||
913 | * |
||
914 | * @return Product |
||
915 | */ |
||
916 | 18 | public function addProductTag(\Eccube\Entity\ProductTag $productTag) |
|
922 | |||
923 | /** |
||
924 | * Remove productTag. |
||
925 | * |
||
926 | * @param \Eccube\Entity\ProductTag $productTag |
||
927 | * |
||
928 | * @return boolean TRUE if this collection contained the specified element, FALSE otherwise. |
||
929 | */ |
||
930 | 2 | public function removeProductTag(\Eccube\Entity\ProductTag $productTag) |
|
934 | |||
935 | /** |
||
936 | * Get productTag. |
||
937 | * |
||
938 | * @return \Doctrine\Common\Collections\Collection |
||
939 | */ |
||
940 | 40 | public function getProductTag() |
|
944 | |||
945 | /** |
||
946 | * Get Tag |
||
947 | * フロント側タグsort_no順の配列を作成する |
||
948 | * |
||
949 | * @return []Tag |
||
950 | */ |
||
951 | 31 | public function getTags() |
|
952 | { |
||
953 | 31 | $tags = []; |
|
954 | |||
955 | 31 | foreach ($this->getProductTag() as $productTag) { |
|
956 | 1 | $tags[] = $productTag->getTag(); |
|
957 | } |
||
958 | |||
959 | 31 | usort($tags, function (Tag $tag1, Tag $tag2) { |
|
960 | return $tag1->getSortNo() < $tag2->getSortNo(); |
||
961 | 31 | }); |
|
962 | |||
963 | 31 | return $tags; |
|
964 | } |
||
965 | |||
966 | /** |
||
967 | * Add customerFavoriteProduct. |
||
968 | * |
||
969 | * @param \Eccube\Entity\CustomerFavoriteProduct $customerFavoriteProduct |
||
970 | * |
||
971 | * @return Product |
||
972 | */ |
||
973 | public function addCustomerFavoriteProduct(\Eccube\Entity\CustomerFavoriteProduct $customerFavoriteProduct) |
||
979 | |||
980 | /** |
||
981 | * Remove customerFavoriteProduct. |
||
982 | * |
||
983 | * @param \Eccube\Entity\CustomerFavoriteProduct $customerFavoriteProduct |
||
984 | * |
||
985 | * @return boolean TRUE if this collection contained the specified element, FALSE otherwise. |
||
986 | */ |
||
987 | public function removeCustomerFavoriteProduct(\Eccube\Entity\CustomerFavoriteProduct $customerFavoriteProduct) |
||
991 | |||
992 | /** |
||
993 | * Get customerFavoriteProducts. |
||
994 | * |
||
995 | * @return \Doctrine\Common\Collections\Collection |
||
996 | */ |
||
997 | public function getCustomerFavoriteProducts() |
||
1001 | |||
1002 | /** |
||
1003 | * Set creator. |
||
1004 | * |
||
1005 | * @param \Eccube\Entity\Member|null $creator |
||
1006 | * |
||
1007 | * @return Product |
||
1008 | */ |
||
1009 | 366 | public function setCreator(\Eccube\Entity\Member $creator = null) |
|
1015 | |||
1016 | /** |
||
1017 | * Get creator. |
||
1018 | * |
||
1019 | * @return \Eccube\Entity\Member|null |
||
1020 | */ |
||
1021 | 12 | public function getCreator() |
|
1025 | |||
1026 | /** |
||
1027 | * Set status. |
||
1028 | * |
||
1029 | * @param \Eccube\Entity\Master\ProductStatus|null $status |
||
1030 | * |
||
1031 | * @return Product |
||
1032 | */ |
||
1033 | 364 | public function setStatus(\Eccube\Entity\Master\ProductStatus $status = null) |
|
1039 | |||
1040 | /** |
||
1041 | * Get status. |
||
1042 | * |
||
1043 | * @return \Eccube\Entity\Master\ProductStatus|null |
||
1044 | */ |
||
1045 | 106 | public function getStatus() |
|
1049 | } |
||
1050 |
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.