Complex classes like User 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 User, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 36 | class User extends Person implements UserInterface, \Serializable |
||
| 37 | { |
||
| 38 | /** |
||
| 39 | * @ORM\Id |
||
| 40 | * @ORM\Column(type="integer") |
||
| 41 | * @ORM\GeneratedValue |
||
| 42 | * @var int |
||
| 43 | */ |
||
| 44 | protected $id; |
||
| 45 | |||
| 46 | /** |
||
| 47 | * @ORM\Column(type="string", nullable=true) |
||
| 48 | * @Assert\Regex(pattern="/[@ ]{1,}/", match=false, message="login_username.invalid_chars", htmlPattern=false) |
||
| 49 | * @Assert\Length(min=5) |
||
| 50 | * @var string |
||
| 51 | */ |
||
| 52 | protected $loginUsername; |
||
| 53 | |||
| 54 | /** |
||
| 55 | * @ORM\Column(type="string", nullable=true) |
||
| 56 | * @Assert\Length(min=7) |
||
| 57 | * @var string |
||
| 58 | */ |
||
| 59 | protected $password; |
||
| 60 | |||
| 61 | /** |
||
| 62 | * @ORM\Column(type="string", nullable=true) |
||
| 63 | * @var string |
||
| 64 | */ |
||
| 65 | protected $token; |
||
| 66 | |||
| 67 | /** |
||
| 68 | * @ORM\Column(type="datetime", nullable=true) |
||
| 69 | * @var \DateTime |
||
| 70 | */ |
||
| 71 | protected $tokenValidity; |
||
| 72 | |||
| 73 | /** |
||
| 74 | * @ORM\Column(type="boolean") |
||
| 75 | * @var bool |
||
| 76 | */ |
||
| 77 | protected $enabled; |
||
| 78 | |||
| 79 | /** |
||
| 80 | * @ORM\Column(type="boolean") |
||
| 81 | * @var bool |
||
| 82 | */ |
||
| 83 | protected $globalAdministrator; |
||
| 84 | |||
| 85 | /** |
||
| 86 | * @ORM\Column(type="boolean") |
||
| 87 | * @var bool |
||
| 88 | */ |
||
| 89 | protected $financialManager; |
||
| 90 | |||
| 91 | /** |
||
| 92 | * @ORM\Column(type="boolean") |
||
| 93 | * @var bool |
||
| 94 | */ |
||
| 95 | protected $allowExternalLogin; |
||
| 96 | |||
| 97 | /** |
||
| 98 | * @ORM\Column(type="boolean") |
||
| 99 | * @var bool |
||
| 100 | */ |
||
| 101 | protected $externalLogin; |
||
| 102 | |||
| 103 | /** |
||
| 104 | * @ORM\Column(type="datetime", nullable=true) |
||
| 105 | * @var \DateTime |
||
| 106 | */ |
||
| 107 | protected $lastLogin; |
||
| 108 | |||
| 109 | /** |
||
| 110 | * @ORM\ManyToOne(targetEntity="Group", inversedBy="students") |
||
| 111 | * |
||
| 112 | * @var Group |
||
| 113 | */ |
||
| 114 | protected $studentGroup; |
||
| 115 | |||
| 116 | /** |
||
| 117 | * @ORM\ManyToMany(targetEntity="Group", mappedBy="tutors", fetch="EXTRA_LAZY") |
||
| 118 | * @ORM\JoinTable(name="tutorized_groups") |
||
| 119 | * |
||
| 120 | * @var Collection |
||
| 121 | */ |
||
| 122 | protected $tutorizedGroups; |
||
| 123 | |||
| 124 | /** |
||
| 125 | * @ORM\OneToMany(targetEntity="Department", mappedBy="head", fetch="EXTRA_LAZY") |
||
| 126 | * |
||
| 127 | * @var Collection |
||
| 128 | */ |
||
| 129 | protected $directs; |
||
| 130 | |||
| 131 | /** |
||
| 132 | * @ORM\OneToMany(targetEntity="Agreement", mappedBy="student", fetch="EXTRA_LAZY") |
||
| 133 | * @ORM\OrderBy({"fromDate": "ASC"}) |
||
| 134 | * |
||
| 135 | * @var Collection |
||
| 136 | */ |
||
| 137 | protected $studentAgreements; |
||
| 138 | |||
| 139 | /** |
||
| 140 | * @ORM\OneToMany(targetEntity="Agreement", mappedBy="educationalTutor", fetch="EXTRA_LAZY") |
||
| 141 | * @ORM\OrderBy({"fromDate": "ASC"}) |
||
| 142 | * |
||
| 143 | * @var Collection |
||
| 144 | */ |
||
| 145 | protected $educationalTutorAgreements; |
||
| 146 | |||
| 147 | /** |
||
| 148 | * @ORM\OneToMany(targetEntity="Agreement", mappedBy="workTutor", fetch="EXTRA_LAZY") |
||
| 149 | * @ORM\OrderBy({"fromDate": "ASC"}) |
||
| 150 | * |
||
| 151 | * @var Collection |
||
| 152 | */ |
||
| 153 | protected $workTutorAgreements; |
||
| 154 | |||
| 155 | /** |
||
| 156 | * @ORM\OneToMany(targetEntity="Expense", mappedBy="teacher", fetch="EXTRA_LAZY") |
||
| 157 | * @ORM\OrderBy({"date": "ASC"}) |
||
| 158 | * |
||
| 159 | * @var Collection |
||
| 160 | */ |
||
| 161 | protected $expenses; |
||
| 162 | |||
| 163 | /** |
||
| 164 | * @ORM\OneToMany(targetEntity="Visit", mappedBy="tutor", fetch="EXTRA_LAZY") |
||
| 165 | * @ORM\OrderBy({"date": "ASC"}) |
||
| 166 | * @var Collection |
||
| 167 | */ |
||
| 168 | protected $visits; |
||
| 169 | |||
| 170 | /** |
||
| 171 | * Constructor |
||
| 172 | */ |
||
| 173 | public function __construct() |
||
| 188 | |||
| 189 | /** |
||
| 190 | * Returns the person's display name |
||
| 191 | * |
||
| 192 | * @return string |
||
| 193 | */ |
||
| 194 | public function getFullDisplayName() |
||
| 204 | |||
| 205 | /** |
||
| 206 | * Returns the person's display name |
||
| 207 | * |
||
| 208 | * @return string |
||
| 209 | */ |
||
| 210 | public function getFullPersonDisplayName() |
||
| 220 | |||
| 221 | /** |
||
| 222 | * Get id |
||
| 223 | * |
||
| 224 | * @return integer |
||
| 225 | */ |
||
| 226 | public function getId() |
||
| 227 | { |
||
| 228 | return $this->id; |
||
| 229 | } |
||
| 230 | |||
| 231 | /** |
||
| 232 | * Get login username |
||
| 233 | * |
||
| 234 | * @return string |
||
| 235 | */ |
||
| 236 | public function getLoginUsername() |
||
| 240 | |||
| 241 | /** |
||
| 242 | * Set login username |
||
| 243 | * |
||
| 244 | * @param string $loginUsername |
||
| 245 | * |
||
| 246 | * @return User |
||
| 247 | */ |
||
| 248 | public function setLoginUsername($loginUsername) |
||
| 254 | |||
| 255 | /** |
||
| 256 | * Get password |
||
| 257 | * |
||
| 258 | * @return string |
||
| 259 | */ |
||
| 260 | public function getPassword() |
||
| 264 | |||
| 265 | /** |
||
| 266 | * Set password |
||
| 267 | * |
||
| 268 | * @param string $password |
||
| 269 | * |
||
| 270 | * @return User |
||
| 271 | */ |
||
| 272 | public function setPassword($password) |
||
| 278 | |||
| 279 | /** |
||
| 280 | * Get token |
||
| 281 | * |
||
| 282 | * @return string |
||
| 283 | */ |
||
| 284 | public function getToken() |
||
| 288 | |||
| 289 | /** |
||
| 290 | * Set token |
||
| 291 | * |
||
| 292 | * @param string $token |
||
| 293 | * |
||
| 294 | * @return User |
||
| 295 | */ |
||
| 296 | public function setToken($token) |
||
| 302 | |||
| 303 | /** |
||
| 304 | * Get tokenValidity |
||
| 305 | * |
||
| 306 | * @return \DateTime |
||
| 307 | */ |
||
| 308 | public function getTokenValidity() |
||
| 312 | |||
| 313 | /** |
||
| 314 | * Set tokenValidity |
||
| 315 | * |
||
| 316 | * @param \DateTime $tokenValidity |
||
| 317 | * |
||
| 318 | * @return User |
||
| 319 | */ |
||
| 320 | public function setTokenValidity($tokenValidity) |
||
| 326 | |||
| 327 | /** |
||
| 328 | * Get enabled |
||
| 329 | * |
||
| 330 | * @return boolean |
||
| 331 | */ |
||
| 332 | public function isEnabled() |
||
| 336 | |||
| 337 | /** |
||
| 338 | * Set enabled |
||
| 339 | * |
||
| 340 | * @param boolean $enabled |
||
| 341 | * |
||
| 342 | * @return User |
||
| 343 | */ |
||
| 344 | public function setEnabled($enabled) |
||
| 345 | { |
||
| 346 | $this->enabled = $enabled; |
||
| 347 | |||
| 348 | return $this; |
||
| 349 | } |
||
| 350 | |||
| 351 | /** |
||
| 352 | * Get globalAdministrator |
||
| 353 | * |
||
| 354 | * @return boolean |
||
| 355 | */ |
||
| 356 | public function isGlobalAdministrator() |
||
| 360 | |||
| 361 | /** |
||
| 362 | * Set globalAdministrator |
||
| 363 | * |
||
| 364 | * @param boolean $globalAdministrator |
||
| 365 | * |
||
| 366 | * @return User |
||
| 367 | */ |
||
| 368 | public function setGlobalAdministrator($globalAdministrator) |
||
| 374 | |||
| 375 | /** |
||
| 376 | * String representation of object |
||
| 377 | * @link http://php.net/manual/en/serializable.serialize.php |
||
| 378 | * @return string the string representation of the object or null |
||
| 379 | * @since 5.1.0 |
||
| 380 | */ |
||
| 381 | public function serialize() |
||
| 390 | |||
| 391 | /** |
||
| 392 | * Constructs the object |
||
| 393 | * @link http://php.net/manual/en/serializable.unserialize.php |
||
| 394 | * @param string $serialized <p> |
||
| 395 | * The string representation of the object. |
||
| 396 | * </p> |
||
| 397 | * @return void |
||
| 398 | * @since 5.1.0 |
||
| 399 | */ |
||
| 400 | public function unserialize($serialized) |
||
| 409 | |||
| 410 | /** |
||
| 411 | * Returns the salt that was originally used to encode the password. |
||
| 412 | * |
||
| 413 | * This can return null if the password was not encoded using a salt. |
||
| 414 | * |
||
| 415 | * @return string|null The salt |
||
| 416 | */ |
||
| 417 | public function getSalt() |
||
| 421 | |||
| 422 | /** |
||
| 423 | * Removes sensitive data from the user. |
||
| 424 | * |
||
| 425 | * This is important if, at any given point, sensitive information like |
||
| 426 | * the plain-text password is stored on this object. |
||
| 427 | */ |
||
| 428 | public function eraseCredentials() |
||
| 431 | |||
| 432 | /** |
||
| 433 | * Returns the roles granted to the user. |
||
| 434 | * |
||
| 435 | * @return Role[] The user roles |
||
| 436 | */ |
||
| 437 | public function getRoles() |
||
| 467 | |||
| 468 | /** |
||
| 469 | * Set lastLogin |
||
| 470 | * |
||
| 471 | * @param \DateTime $lastLogin |
||
| 472 | * |
||
| 473 | * @return User |
||
| 474 | */ |
||
| 475 | public function setLastLogin($lastLogin) |
||
| 481 | |||
| 482 | /** |
||
| 483 | * Get lastLogin |
||
| 484 | * |
||
| 485 | * @return \DateTime |
||
| 486 | */ |
||
| 487 | public function getLastLogin() |
||
| 491 | |||
| 492 | /** |
||
| 493 | * Set group |
||
| 494 | * |
||
| 495 | * @param Group $group |
||
| 496 | * |
||
| 497 | * @return User |
||
| 498 | */ |
||
| 499 | public function setStudentGroup(Group $group = null) |
||
| 505 | |||
| 506 | /** |
||
| 507 | * Get group |
||
| 508 | * |
||
| 509 | * @return Group |
||
| 510 | */ |
||
| 511 | public function getStudentGroup() |
||
| 515 | |||
| 516 | /** |
||
| 517 | * Add tutorizedGroup |
||
| 518 | * |
||
| 519 | * @param Group $tutorizedGroup |
||
| 520 | * |
||
| 521 | * @return User |
||
| 522 | */ |
||
| 523 | public function addTutorizedGroup(Group $tutorizedGroup) |
||
| 532 | |||
| 533 | /** |
||
| 534 | * Remove tutorizedGroup |
||
| 535 | * |
||
| 536 | * @param Group $tutorizedGroup |
||
| 537 | */ |
||
| 538 | public function removeTutorizedGroup(Group $tutorizedGroup) |
||
| 545 | |||
| 546 | /** |
||
| 547 | * Get tutorizedGroups |
||
| 548 | * |
||
| 549 | * @return Collection |
||
| 550 | */ |
||
| 551 | public function getTutorizedGroups() |
||
| 555 | |||
| 556 | /** |
||
| 557 | * Add direct |
||
| 558 | * |
||
| 559 | * @param Department $direct |
||
| 560 | * |
||
| 561 | * @return User |
||
| 562 | */ |
||
| 563 | public function addDirect(Department $direct) |
||
| 569 | |||
| 570 | /** |
||
| 571 | * Remove direct |
||
| 572 | * |
||
| 573 | * @param Department $direct |
||
| 574 | */ |
||
| 575 | public function removeDirect(Department $direct) |
||
| 579 | |||
| 580 | /** |
||
| 581 | * Get directs |
||
| 582 | * |
||
| 583 | * @return Collection |
||
| 584 | */ |
||
| 585 | public function getDirects() |
||
| 589 | |||
| 590 | /** |
||
| 591 | * @Assert\Callback |
||
| 592 | */ |
||
| 593 | public function validate(ExecutionContextInterface $context) |
||
| 605 | |||
| 606 | /** |
||
| 607 | * Returns the username used to authenticate the user. |
||
| 608 | * |
||
| 609 | * @return string The username |
||
| 610 | */ |
||
| 611 | public function getUsername() |
||
| 615 | |||
| 616 | /** |
||
| 617 | * Add studentAgreement |
||
| 618 | * |
||
| 619 | * @param Agreement $studentAgreement |
||
| 620 | * |
||
| 621 | * @return User |
||
| 622 | */ |
||
| 623 | public function addStudentAgreement(Agreement $studentAgreement) |
||
| 629 | |||
| 630 | /** |
||
| 631 | * Remove studentAgreement |
||
| 632 | * |
||
| 633 | * @param Agreement $studentAgreement |
||
| 634 | */ |
||
| 635 | public function removeStudentAgreement(Agreement $studentAgreement) |
||
| 639 | |||
| 640 | /** |
||
| 641 | * Get studentAgreements |
||
| 642 | * |
||
| 643 | * @return Collection |
||
| 644 | */ |
||
| 645 | public function getStudentAgreements() |
||
| 649 | |||
| 650 | /** |
||
| 651 | * Add educationalTutorAgreement |
||
| 652 | * |
||
| 653 | * @param Agreement $educationalTutorAgreement |
||
| 654 | * |
||
| 655 | * @return User |
||
| 656 | */ |
||
| 657 | public function addEducationalTutorAgreement(Agreement $educationalTutorAgreement) |
||
| 663 | |||
| 664 | /** |
||
| 665 | * Remove educationalTutorAgreement |
||
| 666 | * |
||
| 667 | * @param Agreement $educationalTutorAgreement |
||
| 668 | */ |
||
| 669 | public function removeEducationalTutorAgreement(Agreement $educationalTutorAgreement) |
||
| 673 | |||
| 674 | /** |
||
| 675 | * Get educationalTutorAgreements |
||
| 676 | * |
||
| 677 | * @return Collection |
||
| 678 | */ |
||
| 679 | public function getEducationalTutorAgreements() |
||
| 683 | |||
| 684 | /** |
||
| 685 | * Add workTutorAgreement |
||
| 686 | * |
||
| 687 | * @param Agreement $workTutorAgreement |
||
| 688 | * |
||
| 689 | * @return User |
||
| 690 | */ |
||
| 691 | public function addWorkTutorAgreement(Agreement $workTutorAgreement) |
||
| 697 | |||
| 698 | /** |
||
| 699 | * Remove workTutorAgreement |
||
| 700 | * |
||
| 701 | * @param Agreement $workTutorAgreement |
||
| 702 | */ |
||
| 703 | public function removeWorkTutorAgreement(Agreement $workTutorAgreement) |
||
| 707 | |||
| 708 | /** |
||
| 709 | * Get workTutorAgreements |
||
| 710 | * |
||
| 711 | * @return Collection |
||
| 712 | */ |
||
| 713 | public function getWorkTutorAgreements() |
||
| 717 | |||
| 718 | /** |
||
| 719 | * Add expense |
||
| 720 | * |
||
| 721 | * @param \AppBundle\Entity\Expense $expense |
||
| 722 | * |
||
| 723 | * @return User |
||
| 724 | */ |
||
| 725 | public function addExpense(\AppBundle\Entity\Expense $expense) |
||
| 731 | |||
| 732 | /** |
||
| 733 | * Remove expense |
||
| 734 | * |
||
| 735 | * @param \AppBundle\Entity\Expense $expense |
||
| 736 | */ |
||
| 737 | public function removeExpense(\AppBundle\Entity\Expense $expense) |
||
| 741 | |||
| 742 | /** |
||
| 743 | * Get expenses |
||
| 744 | * |
||
| 745 | * @return Collection |
||
| 746 | */ |
||
| 747 | public function getExpenses() |
||
| 751 | |||
| 752 | /** |
||
| 753 | * Add visit |
||
| 754 | * |
||
| 755 | * @param Visit $visit |
||
| 756 | * |
||
| 757 | * @return User |
||
| 758 | */ |
||
| 759 | public function addVisit(Visit $visit) |
||
| 765 | |||
| 766 | /** |
||
| 767 | * Remove visit |
||
| 768 | * |
||
| 769 | * @param Visit $visit |
||
| 770 | */ |
||
| 771 | public function removeVisit(Visit $visit) |
||
| 775 | |||
| 776 | /** |
||
| 777 | * Get visits |
||
| 778 | * |
||
| 779 | * @return Collection |
||
| 780 | */ |
||
| 781 | public function getVisits() |
||
| 785 | |||
| 786 | /** |
||
| 787 | * Set financialManager |
||
| 788 | * |
||
| 789 | * @param boolean $financialManager |
||
| 790 | * |
||
| 791 | * @return User |
||
| 792 | */ |
||
| 793 | public function setFinancialManager($financialManager) |
||
| 799 | |||
| 800 | /** |
||
| 801 | * Get financialManager |
||
| 802 | * |
||
| 803 | * @return boolean |
||
| 804 | */ |
||
| 805 | public function isFinancialManager() |
||
| 809 | |||
| 810 | /** |
||
| 811 | * Get allowExternalLogin |
||
| 812 | * |
||
| 813 | * @return bool |
||
| 814 | */ |
||
| 815 | public function getAllowExternalLogin() |
||
| 819 | |||
| 820 | /** |
||
| 821 | * Set allowExternalLogin |
||
| 822 | * |
||
| 823 | * @param bool $allowExternalLogin |
||
| 824 | * |
||
| 825 | * @return User |
||
| 826 | */ |
||
| 827 | public function setAllowExternalLogin($allowExternalLogin) |
||
| 832 | |||
| 833 | /** |
||
| 834 | * Has externalLogin |
||
| 835 | * |
||
| 836 | * @return bool |
||
| 837 | */ |
||
| 838 | public function hasExternalLogin() |
||
| 842 | |||
| 843 | /** |
||
| 844 | * Set externalLogin |
||
| 845 | * |
||
| 846 | * @param bool $externalLogin |
||
| 847 | * @return User |
||
| 848 | */ |
||
| 849 | public function setExternalLogin($externalLogin) |
||
| 854 | } |
||
| 855 |
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.