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 EventManager 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 EventManager, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
27 | class EventManager extends AbstractManager |
||
28 | { |
||
29 | use CategoryTrait; |
||
30 | |||
31 | /** @var EventInterface $currentEvent The current event. */ |
||
32 | private $currentEvent; |
||
33 | |||
34 | /** @var integer $currentPage The current Page. */ |
||
35 | private $currentPage; |
||
36 | |||
37 | /** @var integer $numPerPage Events by page. */ |
||
38 | private $numPerPage = 0; |
||
39 | |||
40 | /** @var integer $numPage How many pages. */ |
||
41 | private $numPage; |
||
42 | |||
43 | /** @var boolean $entryCycle Does the pager can cycle indefinitely. */ |
||
44 | private $entryCycle = false; |
||
45 | |||
46 | /** @var EventInterface $nextEvent */ |
||
47 | private $nextEvent; |
||
48 | |||
49 | /** @var EventInterface $prevEvent */ |
||
50 | private $prevEvent; |
||
51 | |||
52 | /** @var integer $page The page number. */ |
||
53 | private $page = 0; |
||
54 | |||
55 | /** @var integer $category Id for category. */ |
||
56 | private $category = 0; |
||
57 | |||
58 | /** @var EventInterface[] $all All the events. */ |
||
59 | private $all = []; |
||
60 | |||
61 | /** @var EventInterface[] $entries The event collection. */ |
||
62 | private $entries = []; |
||
63 | |||
64 | /** @var EventInterface[] $archive The archive events collection. */ |
||
65 | private $archive = []; |
||
66 | |||
67 | /** @var EventInterface $entry An event. */ |
||
68 | private $entry; |
||
69 | |||
70 | /** @var object $objType The event object model. */ |
||
71 | private $objType; |
||
72 | |||
73 | /** @var string $featIdent The config ident for featured events. */ |
||
74 | private $featIdent; |
||
75 | |||
76 | /** @var EventInterface[] $featList The config ident for featured events. */ |
||
77 | private $featList = []; |
||
78 | |||
79 | /** @var EventLoader $loader The event loader provider. */ |
||
80 | private $loader; |
||
81 | |||
82 | /** @var array $mapEvents The events mapped per [year][month][date]. */ |
||
83 | private $mapEvents = []; |
||
84 | |||
85 | /** @var datetime $date Datetime filter */ |
||
86 | private $date; |
||
87 | |||
88 | /** @var mixed $year Year filter. */ |
||
89 | private $year; |
||
90 | |||
91 | /** @var mixed $month Month filter. */ |
||
92 | private $month; |
||
93 | |||
94 | /** @var mixed $day Day filter. */ |
||
95 | private $day; |
||
96 | |||
97 | /** |
||
98 | * EventManager constructor. |
||
99 | * @param array $data The Data. |
||
100 | * @throws Exception When $data index is not set. |
||
101 | */ |
||
102 | View Code Duplication | public function __construct(array $data) |
|
122 | |||
123 | /** |
||
124 | * To be displayed events list. |
||
125 | * @return mixed The event collection. |
||
126 | */ |
||
127 | public function entries() |
||
230 | |||
231 | /** |
||
232 | * @param integer|null $id The event id. |
||
233 | * @return mixed |
||
234 | */ |
||
235 | View Code Duplication | public function entry($id = null) |
|
251 | |||
252 | /** |
||
253 | * All available events |
||
254 | * @return EventInterface[]|Collection The events collection |
||
255 | */ |
||
256 | public function all() |
||
267 | |||
268 | /** |
||
269 | * @return CategoryInterface[]|Collection The category collection. |
||
270 | */ |
||
271 | View Code Duplication | public function loadCategoryItems() |
|
281 | |||
282 | /** |
||
283 | * @param integer $id The category id. |
||
284 | * @return CategoryInterface|EventCategory |
||
285 | */ |
||
286 | public function categoryItem($id) |
||
292 | |||
293 | /** |
||
294 | * Get featured events from config objects with custom filters as options. |
||
295 | * @return mixed |
||
296 | * @param array $options The options for the collection loader. |
||
297 | * @throws Exception When featured news ident is not valid. |
||
298 | */ |
||
299 | View Code Duplication | public function featList(array $options = []) |
|
355 | |||
356 | /** |
||
357 | * @return EventInterface[]|Collection |
||
358 | */ |
||
359 | View Code Duplication | public function archive() |
|
383 | |||
384 | /** |
||
385 | * Get the latest event. |
||
386 | * @return EventInterface|array The latest event. |
||
387 | */ |
||
388 | View Code Duplication | public function latest() |
|
399 | |||
400 | /** |
||
401 | * @return mixed The previous event |
||
402 | */ |
||
403 | public function prev() |
||
411 | |||
412 | /** |
||
413 | * @return mixed The next event |
||
414 | */ |
||
415 | public function next() |
||
423 | |||
424 | /** |
||
425 | * @return float|int The current event index page ident. |
||
426 | */ |
||
427 | View Code Duplication | public function currentPage() |
|
450 | |||
451 | /** |
||
452 | * @param mixed $date The date from which to load. |
||
453 | * @return array |
||
454 | */ |
||
455 | public function getEventsByDate($date) |
||
472 | |||
473 | // ========================================================================== |
||
474 | // GETTERS |
||
475 | // ========================================================================== |
||
476 | |||
477 | /** |
||
478 | * @return mixed |
||
479 | */ |
||
480 | public function currentEvent() |
||
488 | |||
489 | /** |
||
490 | * @return integer |
||
491 | */ |
||
492 | public function numPerPage() |
||
496 | |||
497 | /** |
||
498 | * @return boolean |
||
499 | */ |
||
500 | public function entryCycle() |
||
504 | |||
505 | /** |
||
506 | * Amount of event (total) |
||
507 | * @return integer How many event? |
||
508 | */ |
||
509 | public function numEvent() |
||
513 | |||
514 | /** |
||
515 | * The total amount of pages. |
||
516 | * @return float |
||
517 | */ |
||
518 | View Code Duplication | public function numPages() |
|
535 | |||
536 | /** |
||
537 | * Is there a pager. |
||
538 | * @return boolean |
||
539 | */ |
||
540 | public function hasPager() |
||
544 | |||
545 | /** |
||
546 | * @return integer |
||
547 | */ |
||
548 | public function page() |
||
552 | |||
553 | /** |
||
554 | * @return integer |
||
555 | */ |
||
556 | public function category() |
||
560 | |||
561 | /** |
||
562 | * @return mixed |
||
563 | */ |
||
564 | public function objType() |
||
568 | |||
569 | /** |
||
570 | * @return mixed |
||
571 | */ |
||
572 | public function featIdent() |
||
576 | |||
577 | /** |
||
578 | * @return EventLoader |
||
579 | */ |
||
580 | public function loader() |
||
584 | |||
585 | /** |
||
586 | * Datetime object OR null. |
||
587 | * @return mixed Datetime or null. |
||
588 | */ |
||
589 | public function date() |
||
593 | |||
594 | /** |
||
595 | * Full year |
||
596 | * @return integer Full year. |
||
597 | */ |
||
598 | public function year() |
||
602 | |||
603 | /** |
||
604 | * Month |
||
605 | * @return mixed month. |
||
606 | */ |
||
607 | public function month() |
||
611 | |||
612 | /** |
||
613 | * Day |
||
614 | * @return mixed day. |
||
615 | */ |
||
616 | public function day() |
||
620 | |||
621 | // ========================================================================== |
||
622 | // SETTERS |
||
623 | // ========================================================================== |
||
624 | |||
625 | /** |
||
626 | * @param mixed $currentEvent The current event context. |
||
627 | * @return self |
||
628 | */ |
||
629 | public function setCurrentEvent($currentEvent) |
||
635 | |||
636 | /** |
||
637 | * @param integer $numPerPage The number of event per page. |
||
638 | * @return self |
||
639 | */ |
||
640 | public function setNumPerPage($numPerPage) |
||
646 | |||
647 | /** |
||
648 | * @param boolean $entryCycle Next and Prev cycles indefinitely. |
||
649 | * @return self |
||
650 | */ |
||
651 | public function setEntryCycle($entryCycle) |
||
657 | |||
658 | /** |
||
659 | * @param integer $page The page number to load. |
||
660 | * @return self |
||
661 | */ |
||
662 | public function setPage($page) |
||
668 | |||
669 | /** |
||
670 | * @param integer $category The current entry category. |
||
671 | * @return self |
||
672 | */ |
||
673 | public function setCategory($category) |
||
679 | |||
680 | /** |
||
681 | * @param mixed $objType The object type. |
||
682 | * @return self |
||
683 | */ |
||
684 | public function setObjType($objType) |
||
690 | |||
691 | /** |
||
692 | * @param mixed $featIdent The featured list ident. |
||
693 | * @return self |
||
694 | */ |
||
695 | public function setFeatIdent($featIdent) |
||
701 | |||
702 | /** |
||
703 | * @param EventLoader|null $loader The event loader provider. |
||
704 | * @return self |
||
705 | */ |
||
706 | public function setLoader($loader) |
||
712 | |||
713 | /** |
||
714 | * Set date filter. |
||
715 | * @param DateTime $date Date filter. |
||
716 | * @return self |
||
717 | */ |
||
718 | public function setDate(DateTime $date) |
||
724 | |||
725 | /** |
||
726 | * Full year. |
||
727 | * @param mixed $year Full year. |
||
728 | * @throws Exception If argument is not scalar. |
||
729 | * @return EventManager |
||
730 | */ |
||
731 | public function setYear($year) |
||
740 | |||
741 | /** |
||
742 | * Month. |
||
743 | * @param mixed $month Specific month. |
||
744 | * @throws Exception If argument is not scalar. |
||
745 | * @return EventManager |
||
746 | */ |
||
747 | public function setMonth($month) |
||
756 | |||
757 | /** |
||
758 | * Day. |
||
759 | * @param mixed $day Specific day. |
||
760 | * @throws Exception If argument is not scalar. |
||
761 | * @return EventManager |
||
762 | */ |
||
763 | public function setDay($day) |
||
772 | |||
773 | // ========================================================================== |
||
774 | // UTILS |
||
775 | // ========================================================================== |
||
776 | |||
777 | /** |
||
778 | * Set the Prev and Next event |
||
779 | * @return $this |
||
780 | */ |
||
781 | View Code Duplication | public function setPrevNext() |
|
829 | |||
830 | /** |
||
831 | * Mapping between events and dates |
||
832 | * @return array The array containing events stored as [$year][$month][$day][event] |
||
833 | */ |
||
834 | public function mapEvents() |
||
877 | } |
||
878 |
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.