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 LargePermission 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 LargePermission, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
42 | class LargePermission extends MediumPermission |
||
43 | { |
||
44 | /** |
||
45 | * Default data for new sections. |
||
46 | * |
||
47 | * @var array |
||
48 | */ |
||
49 | public $defaultSectionData = [ |
||
50 | 'name' => 'DEFAULT_SECTION', |
||
51 | 'description' => 'Short section description.', |
||
52 | ]; |
||
53 | |||
54 | /** |
||
55 | * Constructor. |
||
56 | * |
||
57 | * @param Configuration $config |
||
58 | */ |
||
59 | public function __construct(Configuration $config) |
||
63 | |||
64 | /** |
||
65 | * Returns true, if the user given by $userId owns the right |
||
66 | * specified by $right in a section. It does not matter if |
||
67 | * the user owns this right as a user-right or because of a |
||
68 | * group-membership in a section. The parameter $right may |
||
69 | * be a right-ID (recommended for performance) or a right-name. |
||
70 | * |
||
71 | * @param int $userId |
||
72 | * @param mixed $right |
||
73 | * |
||
74 | * @return bool |
||
75 | */ |
||
76 | View Code Duplication | public function checkRight($userId, $right) |
|
100 | |||
101 | /** |
||
102 | * Returns true if the user $userId owns the right $rightId |
||
103 | * because of a section membership, otherwise false. |
||
104 | * |
||
105 | * @param int $userId |
||
106 | * @param int $rightId |
||
107 | * |
||
108 | * @return bool |
||
109 | */ |
||
110 | public function checkUserSectionRight($userId, $rightId) |
||
144 | |||
145 | /** |
||
146 | * Adds a new section to the database and returns the ID of the |
||
147 | * new section. The associative array $sectionData contains the |
||
148 | * data for the new section. |
||
149 | * |
||
150 | * @param array $sectionData Array of section data |
||
151 | * |
||
152 | * @return int |
||
153 | */ |
||
154 | View Code Duplication | public function addSection(Array $sectionData) |
|
182 | |||
183 | /** |
||
184 | * Changes the section data of the given section. |
||
185 | * |
||
186 | * @param int $sectionId |
||
187 | * @param array $sectionData |
||
188 | * @return bool |
||
189 | */ |
||
190 | View Code Duplication | public function changeSection($sectionId, Array $sectionData) |
|
221 | |||
222 | /** |
||
223 | * Checks the given associative array $sectionData. If a |
||
224 | * parameter is incorrect or is missing, it will be replaced |
||
225 | * by the default values in $this->defaultSectionData. |
||
226 | * Returns the corrected $sectionData associative array. |
||
227 | * |
||
228 | * @param array $sectionData |
||
229 | * @return array |
||
230 | */ |
||
231 | public function checkSectionData(Array $sectionData) |
||
242 | |||
243 | /** |
||
244 | * Removes the section given by $sectionId from the database. |
||
245 | * Returns true on success, otherwise false. |
||
246 | * |
||
247 | * @param int $sectionId |
||
248 | * @return bool |
||
249 | */ |
||
250 | View Code Duplication | public function deleteSection($sectionId) |
|
300 | |||
301 | /** |
||
302 | * Returns true if the user given by $userId is a member of |
||
303 | * the section specified by $sectionId, otherwise false. |
||
304 | * |
||
305 | * @param int $userId |
||
306 | * @param int $sectionId |
||
307 | * @return bool |
||
308 | */ |
||
309 | public function isSectionMember($userId, $sectionId) |
||
342 | |||
343 | /** |
||
344 | * Returns an array that contains the user IDs of all members |
||
345 | * of the section $sectionId. |
||
346 | * |
||
347 | * @param int $sectionId |
||
348 | * @return array |
||
349 | */ |
||
350 | public function getSectionMembers($sectionId) |
||
382 | |||
383 | /** |
||
384 | * Returns an array that contains the group IDs of all groups |
||
385 | * of the section $sectionId. |
||
386 | * |
||
387 | * @param int $sectionId |
||
388 | * @return array |
||
389 | */ |
||
390 | View Code Duplication | public function getSectionGroups($sectionId) |
|
419 | |||
420 | /** |
||
421 | * Adds a new group $groupId to the section $sectionId. |
||
422 | * Returns true on success, otherwise false. |
||
423 | * |
||
424 | * @param int $groupId |
||
425 | * @param int $sectionId |
||
426 | * @return bool |
||
427 | */ |
||
428 | public function addGroupToSection($groupId, $sectionId) |
||
473 | |||
474 | /** |
||
475 | * Removes all groups from the section $sectionId. |
||
476 | * Returns true on success, otherwise false. |
||
477 | * |
||
478 | * @param int $sectionId |
||
479 | * @return bool |
||
480 | */ |
||
481 | View Code Duplication | public function removeAllGroupsFromSection($sectionId) |
|
503 | |||
504 | /** |
||
505 | * Removes a group $groupId from the section $sectionId. |
||
506 | * Returns true on success, otherwise false. |
||
507 | * |
||
508 | * @param int $groupId |
||
509 | * @param int $sectionId |
||
510 | * @return bool |
||
511 | */ |
||
512 | public function removeGroupFromSection($groupId, $sectionId) |
||
537 | |||
538 | /** |
||
539 | * Returns the ID of the section that has the name $name. Returns |
||
540 | * 0 if the section name cannot be found. |
||
541 | * |
||
542 | * @param string $name |
||
543 | * @return int |
||
544 | */ |
||
545 | public function getSectionId($name) |
||
566 | |||
567 | /** |
||
568 | * Returns an associative array with the section data of the section |
||
569 | * $sectionId. |
||
570 | * |
||
571 | * @param int $sectionId |
||
572 | * @return array |
||
573 | */ |
||
574 | public function getSectionData($sectionId) |
||
595 | |||
596 | /** |
||
597 | * Returns an array with the IDs of all sections stored in the |
||
598 | * database if no user ID is passed. |
||
599 | * @param int $userId |
||
600 | * @return array |
||
601 | */ |
||
602 | public function getAllSections($userId = 1) |
||
621 | |||
622 | /** |
||
623 | * Returns an array that contains the IDs of all sections in which |
||
624 | * the user $userId is a member. |
||
625 | * |
||
626 | * @param int $userId |
||
627 | * @return array |
||
628 | */ |
||
629 | public function getUserSections($userId) |
||
663 | |||
664 | /** |
||
665 | * Returns an array that contains the right-IDs of all rights |
||
666 | * the user $userId owns. User-rights and the rights the user |
||
667 | * owns because of a section membership are taken into account. |
||
668 | * |
||
669 | * @param int $userId |
||
670 | * @return array |
||
671 | */ |
||
672 | public function getAllUserRights($userId) |
||
683 | |||
684 | /** |
||
685 | * Removes the group $groupId from all sections. |
||
686 | * Returns true on success, otherwise false. |
||
687 | * |
||
688 | * @param int $groupId |
||
689 | * @return bool |
||
690 | */ |
||
691 | View Code Duplication | public function removeGroupFromAllSections($groupId) |
|
712 | |||
713 | /** |
||
714 | * Returns an array that contains the IDs of all rights the user |
||
715 | * $userId owns because of a section membership. |
||
716 | * |
||
717 | * @param int $userId |
||
718 | * @return array |
||
719 | */ |
||
720 | public function getUserSectionRights($userId) |
||
751 | |||
752 | /** |
||
753 | * Returns the name of the section $sectionId. |
||
754 | * |
||
755 | * @param int $sectionId |
||
756 | * @return string |
||
757 | */ |
||
758 | View Code Duplication | public function getSectionName($sectionId) |
|
781 | |||
782 | /** |
||
783 | * Adds a new category $categoryId to the section $sectionId. |
||
784 | * Returns true on success, otherwise false. |
||
785 | * |
||
786 | * @param int $categoryId |
||
787 | * @param int $sectionId |
||
788 | * @return bool |
||
789 | */ |
||
790 | View Code Duplication | public function addCategoryToSection($categoryId, $sectionId) |
|
811 | |||
812 | /** |
||
813 | * Removes a category $categoryId to the section $sectionId. |
||
814 | * Returns true on success, otherwise false. |
||
815 | * |
||
816 | * @param int $categoryId |
||
817 | * @param int $sectionId |
||
818 | * @return bool |
||
819 | */ |
||
820 | View Code Duplication | public function removeCategoryFromSection($categoryId, $sectionId) |
|
842 | |||
843 | /** |
||
844 | * Returns an array that contains the category IDs of all categories |
||
845 | * of the section $sectionId. |
||
846 | * |
||
847 | * @param int $sectionId |
||
848 | * @return array |
||
849 | */ |
||
850 | public function getSectionCategories($sectionId) |
||
872 | |||
873 | /** |
||
874 | * Removes the category $categoryId from all sections. |
||
875 | * Returns true on success, otherwise false. |
||
876 | * |
||
877 | * @param int $categoryId |
||
878 | * @return bool |
||
879 | */ |
||
880 | View Code Duplication | public function removeCategoryFromAllSections($categoryId) |
|
899 | |||
900 | /** |
||
901 | * Adds a new news $newsId to the section $sectionId. |
||
902 | * Returns true on success, otherwise false. |
||
903 | * |
||
904 | * @param int $newsId |
||
905 | * @param int $sectionId |
||
906 | * @return bool |
||
907 | */ |
||
908 | View Code Duplication | public function addNewsToSection($newsId, $sectionId) |
|
929 | |||
930 | /** |
||
931 | * Removes a news $newsId from the section $sectionId. |
||
932 | * Returns true on success, otherwise false. |
||
933 | * |
||
934 | * @param int $newsId |
||
935 | * @param int $sectionId |
||
936 | * @return bool |
||
937 | */ |
||
938 | View Code Duplication | public function removeNewsFromSection($newsId, $sectionId) |
|
960 | |||
961 | /** |
||
962 | * Returns an array that contains the news IDs of all news |
||
963 | * of the section $sectionId. |
||
964 | * |
||
965 | * @param int $sectionId |
||
966 | * @return array |
||
967 | */ |
||
968 | public function getSectionNews($sectionId) |
||
990 | |||
991 | /** |
||
992 | * Removes the news $newsId from all sections. |
||
993 | * Returns true on success, otherwise false. |
||
994 | * |
||
995 | * @param int $newsId |
||
996 | * @return bool |
||
997 | */ |
||
998 | View Code Duplication | public function removeNewsFromAllSections($newsId) |
|
1017 | |||
1018 | } |
||
1019 |
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.