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, EquatableInterface |
||
| 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="datetime", nullable=true) |
||
| 87 | * @var \DateTime |
||
| 88 | */ |
||
| 89 | protected $lastLogin; |
||
| 90 | |||
| 91 | /** |
||
| 92 | * @ORM\ManyToOne(targetEntity="Group", inversedBy="students") |
||
| 93 | * |
||
| 94 | * @var Group |
||
| 95 | */ |
||
| 96 | protected $studentGroup; |
||
| 97 | |||
| 98 | /** |
||
| 99 | * @ORM\ManyToMany(targetEntity="Group", mappedBy="tutors") |
||
| 100 | * @ORM\JoinTable(name="tutorized_groups") |
||
| 101 | * |
||
| 102 | * @var Collection |
||
| 103 | */ |
||
| 104 | protected $tutorizedGroups; |
||
| 105 | |||
| 106 | /** |
||
| 107 | * @ORM\OneToMany(targetEntity="Department", mappedBy="head") |
||
| 108 | * |
||
| 109 | * @var Collection |
||
| 110 | */ |
||
| 111 | protected $directs; |
||
| 112 | |||
| 113 | /** |
||
| 114 | * @ORM\OneToMany(targetEntity="Agreement", mappedBy="student") |
||
| 115 | * @ORM\OrderBy({"fromDate": "ASC"}) |
||
| 116 | * |
||
| 117 | * @var Collection |
||
| 118 | */ |
||
| 119 | protected $studentAgreements; |
||
| 120 | |||
| 121 | /** |
||
| 122 | * @ORM\OneToMany(targetEntity="Agreement", mappedBy="educationalTutor") |
||
| 123 | * @ORM\OrderBy({"fromDate": "ASC"}) |
||
| 124 | * |
||
| 125 | * @var Collection |
||
| 126 | */ |
||
| 127 | protected $educationalTutorAgreements; |
||
| 128 | |||
| 129 | /** |
||
| 130 | * @ORM\OneToMany(targetEntity="Agreement", mappedBy="workTutor") |
||
| 131 | * @ORM\OrderBy({"fromDate": "ASC"}) |
||
| 132 | * |
||
| 133 | * @var Collection |
||
| 134 | */ |
||
| 135 | protected $workTutorAgreements; |
||
| 136 | |||
| 137 | /** |
||
| 138 | * Constructor |
||
| 139 | */ |
||
| 140 | public function __construct() |
||
| 148 | |||
| 149 | /** |
||
| 150 | * Returns the person's display name |
||
| 151 | * |
||
| 152 | * @return string |
||
| 153 | */ |
||
| 154 | public function getFullDisplayName() |
||
| 164 | |||
| 165 | /** |
||
| 166 | * Returns the person's display name |
||
| 167 | * |
||
| 168 | * @return string |
||
| 169 | */ |
||
| 170 | public function getFullPersonDisplayName() |
||
| 180 | |||
| 181 | /** |
||
| 182 | * Get id |
||
| 183 | * |
||
| 184 | * @return integer |
||
| 185 | */ |
||
| 186 | public function getId() |
||
| 187 | { |
||
| 188 | return $this->id; |
||
| 189 | } |
||
| 190 | |||
| 191 | /** |
||
| 192 | * Get login username |
||
| 193 | * |
||
| 194 | * @return string |
||
| 195 | */ |
||
| 196 | public function getLoginUsername() |
||
| 200 | |||
| 201 | /** |
||
| 202 | * Set login username |
||
| 203 | * |
||
| 204 | * @param string $loginUsername |
||
| 205 | * |
||
| 206 | * @return User |
||
| 207 | */ |
||
| 208 | public function setLoginUsername($loginUsername) |
||
| 214 | |||
| 215 | /** |
||
| 216 | * Get password |
||
| 217 | * |
||
| 218 | * @return string |
||
| 219 | */ |
||
| 220 | public function getPassword() |
||
| 224 | |||
| 225 | /** |
||
| 226 | * Set password |
||
| 227 | * |
||
| 228 | * @param string $password |
||
| 229 | * |
||
| 230 | * @return User |
||
| 231 | */ |
||
| 232 | public function setPassword($password) |
||
| 238 | |||
| 239 | /** |
||
| 240 | * Get token |
||
| 241 | * |
||
| 242 | * @return string |
||
| 243 | */ |
||
| 244 | public function getToken() |
||
| 248 | |||
| 249 | /** |
||
| 250 | * Set token |
||
| 251 | * |
||
| 252 | * @param string $token |
||
| 253 | * |
||
| 254 | * @return User |
||
| 255 | */ |
||
| 256 | public function setToken($token) |
||
| 262 | |||
| 263 | /** |
||
| 264 | * Get tokenValidity |
||
| 265 | * |
||
| 266 | * @return \DateTime |
||
| 267 | */ |
||
| 268 | public function getTokenValidity() |
||
| 272 | |||
| 273 | /** |
||
| 274 | * Set tokenValidity |
||
| 275 | * |
||
| 276 | * @param \DateTime $tokenValidity |
||
| 277 | * |
||
| 278 | * @return User |
||
| 279 | */ |
||
| 280 | public function setTokenValidity($tokenValidity) |
||
| 286 | |||
| 287 | /** |
||
| 288 | * Get enabled |
||
| 289 | * |
||
| 290 | * @return boolean |
||
| 291 | */ |
||
| 292 | public function isEnabled() |
||
| 296 | |||
| 297 | /** |
||
| 298 | * Set enabled |
||
| 299 | * |
||
| 300 | * @param boolean $enabled |
||
| 301 | * |
||
| 302 | * @return User |
||
| 303 | */ |
||
| 304 | public function setEnabled($enabled) |
||
| 305 | { |
||
| 306 | $this->enabled = $enabled; |
||
| 307 | |||
| 308 | return $this; |
||
| 309 | } |
||
| 310 | |||
| 311 | /** |
||
| 312 | * Get globalAdministrator |
||
| 313 | * |
||
| 314 | * @return boolean |
||
| 315 | */ |
||
| 316 | public function isGlobalAdministrator() |
||
| 320 | |||
| 321 | /** |
||
| 322 | * Set globalAdministrator |
||
| 323 | * |
||
| 324 | * @param boolean $globalAdministrator |
||
| 325 | * |
||
| 326 | * @return User |
||
| 327 | */ |
||
| 328 | public function setGlobalAdministrator($globalAdministrator) |
||
| 334 | |||
| 335 | /** |
||
| 336 | * String representation of object |
||
| 337 | * @link http://php.net/manual/en/serializable.serialize.php |
||
| 338 | * @return string the string representation of the object or null |
||
| 339 | * @since 5.1.0 |
||
| 340 | */ |
||
| 341 | public function serialize() |
||
| 350 | |||
| 351 | /** |
||
| 352 | * Constructs the object |
||
| 353 | * @link http://php.net/manual/en/serializable.unserialize.php |
||
| 354 | * @param string $serialized <p> |
||
| 355 | * The string representation of the object. |
||
| 356 | * </p> |
||
| 357 | * @return void |
||
| 358 | * @since 5.1.0 |
||
| 359 | */ |
||
| 360 | public function unserialize($serialized) |
||
| 369 | |||
| 370 | /** |
||
| 371 | * The equality comparison should neither be done by referential equality |
||
| 372 | * nor by comparing identities (i.e. getId() === getId()). |
||
| 373 | * |
||
| 374 | * However, you do not need to compare every attribute, but only those that |
||
| 375 | * are relevant for assessing whether re-authentication is required. |
||
| 376 | * |
||
| 377 | * Also implementation should consider that $user instance may implement |
||
| 378 | * the extended user interface `AdvancedUserInterface`. |
||
| 379 | * |
||
| 380 | * @param UserInterface $user |
||
| 381 | * |
||
| 382 | * @return bool |
||
| 383 | */ |
||
| 384 | public function isEqualTo(UserInterface $user) |
||
| 388 | |||
| 389 | /** |
||
| 390 | * Returns the salt that was originally used to encode the password. |
||
| 391 | * |
||
| 392 | * This can return null if the password was not encoded using a salt. |
||
| 393 | * |
||
| 394 | * @return string|null The salt |
||
| 395 | */ |
||
| 396 | public function getSalt() |
||
| 400 | |||
| 401 | /** |
||
| 402 | * Removes sensitive data from the user. |
||
| 403 | * |
||
| 404 | * This is important if, at any given point, sensitive information like |
||
| 405 | * the plain-text password is stored on this object. |
||
| 406 | */ |
||
| 407 | public function eraseCredentials() |
||
| 410 | |||
| 411 | /** |
||
| 412 | * Returns the roles granted to the user. |
||
| 413 | * |
||
| 414 | * @return Role[] The user roles |
||
| 415 | */ |
||
| 416 | public function getRoles() |
||
| 435 | |||
| 436 | /** |
||
| 437 | * Set lastLogin |
||
| 438 | * |
||
| 439 | * @param \DateTime $lastLogin |
||
| 440 | * |
||
| 441 | * @return User |
||
| 442 | */ |
||
| 443 | public function setLastLogin($lastLogin) |
||
| 449 | |||
| 450 | /** |
||
| 451 | * Get lastLogin |
||
| 452 | * |
||
| 453 | * @return \DateTime |
||
| 454 | */ |
||
| 455 | public function getLastLogin() |
||
| 459 | |||
| 460 | /** |
||
| 461 | * Set group |
||
| 462 | * |
||
| 463 | * @param Group $group |
||
| 464 | * |
||
| 465 | * @return User |
||
| 466 | */ |
||
| 467 | public function setStudentGroup(Group $group = null) |
||
| 473 | |||
| 474 | /** |
||
| 475 | * Get group |
||
| 476 | * |
||
| 477 | * @return Group |
||
| 478 | */ |
||
| 479 | public function getStudentGroup() |
||
| 483 | |||
| 484 | /** |
||
| 485 | * Add tutorizedGroup |
||
| 486 | * |
||
| 487 | * @param Group $tutorizedGroup |
||
| 488 | * |
||
| 489 | * @return User |
||
| 490 | */ |
||
| 491 | public function addTutorizedGroup(Group $tutorizedGroup) |
||
| 500 | |||
| 501 | /** |
||
| 502 | * Remove tutorizedGroup |
||
| 503 | * |
||
| 504 | * @param Group $tutorizedGroup |
||
| 505 | */ |
||
| 506 | public function removeTutorizedGroup(Group $tutorizedGroup) |
||
| 513 | |||
| 514 | /** |
||
| 515 | * Get tutorizedGroups |
||
| 516 | * |
||
| 517 | * @return Collection |
||
| 518 | */ |
||
| 519 | public function getTutorizedGroups() |
||
| 523 | |||
| 524 | /** |
||
| 525 | * Add direct |
||
| 526 | * |
||
| 527 | * @param Department $direct |
||
| 528 | * |
||
| 529 | * @return User |
||
| 530 | */ |
||
| 531 | public function addDirect(Department $direct) |
||
| 537 | |||
| 538 | /** |
||
| 539 | * Remove direct |
||
| 540 | * |
||
| 541 | * @param Department $direct |
||
| 542 | */ |
||
| 543 | public function removeDirect(Department $direct) |
||
| 547 | |||
| 548 | /** |
||
| 549 | * Get directs |
||
| 550 | * |
||
| 551 | * @return Collection |
||
| 552 | */ |
||
| 553 | public function getDirects() |
||
| 557 | |||
| 558 | /** |
||
| 559 | * @Assert\Callback |
||
| 560 | */ |
||
| 561 | public function validate(ExecutionContextInterface $context) |
||
| 573 | |||
| 574 | /** |
||
| 575 | * Returns the username used to authenticate the user. |
||
| 576 | * |
||
| 577 | * @return string The username |
||
| 578 | */ |
||
| 579 | public function getUsername() |
||
| 583 | |||
| 584 | /** |
||
| 585 | * Add studentAgreement |
||
| 586 | * |
||
| 587 | * @param Agreement $studentAgreement |
||
| 588 | * |
||
| 589 | * @return User |
||
| 590 | */ |
||
| 591 | public function addStudentAgreement(Agreement $studentAgreement) |
||
| 597 | |||
| 598 | /** |
||
| 599 | * Remove studentAgreement |
||
| 600 | * |
||
| 601 | * @param Agreement $studentAgreement |
||
| 602 | */ |
||
| 603 | public function removeStudentAgreement(Agreement $studentAgreement) |
||
| 607 | |||
| 608 | /** |
||
| 609 | * Get studentAgreements |
||
| 610 | * |
||
| 611 | * @return Collection |
||
| 612 | */ |
||
| 613 | public function getStudentAgreements() |
||
| 617 | |||
| 618 | /** |
||
| 619 | * Add educationalTutorAgreement |
||
| 620 | * |
||
| 621 | * @param \AppBundle\Entity\Agreement $educationalTutorAgreement |
||
| 622 | * |
||
| 623 | * @return User |
||
| 624 | */ |
||
| 625 | public function addEducationalTutorAgreement(\AppBundle\Entity\Agreement $educationalTutorAgreement) |
||
| 631 | |||
| 632 | /** |
||
| 633 | * Remove educationalTutorAgreement |
||
| 634 | * |
||
| 635 | * @param \AppBundle\Entity\Agreement $educationalTutorAgreement |
||
| 636 | */ |
||
| 637 | public function removeEducationalTutorAgreement(\AppBundle\Entity\Agreement $educationalTutorAgreement) |
||
| 641 | |||
| 642 | /** |
||
| 643 | * Get educationalTutorAgreements |
||
| 644 | * |
||
| 645 | * @return \Doctrine\Common\Collections\Collection |
||
| 646 | */ |
||
| 647 | public function getEducationalTutorAgreements() |
||
| 651 | |||
| 652 | /** |
||
| 653 | * Add workTutorAgreement |
||
| 654 | * |
||
| 655 | * @param \AppBundle\Entity\Agreement $workTutorAgreement |
||
| 656 | * |
||
| 657 | * @return User |
||
| 658 | */ |
||
| 659 | public function addWorkTutorAgreement(\AppBundle\Entity\Agreement $workTutorAgreement) |
||
| 665 | |||
| 666 | /** |
||
| 667 | * Remove workTutorAgreement |
||
| 668 | * |
||
| 669 | * @param \AppBundle\Entity\Agreement $workTutorAgreement |
||
| 670 | */ |
||
| 671 | public function removeWorkTutorAgreement(\AppBundle\Entity\Agreement $workTutorAgreement) |
||
| 675 | |||
| 676 | /** |
||
| 677 | * Get workTutorAgreements |
||
| 678 | * |
||
| 679 | * @return \Doctrine\Common\Collections\Collection |
||
| 680 | */ |
||
| 681 | public function getWorkTutorAgreements() |
||
| 685 | } |
||
| 686 |
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.