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 InheritableNameAttributesTrait 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 InheritableNameAttributesTrait, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 32 | trait InheritableNameAttributesTrait |
||
| 33 | { |
||
| 34 | static public $attributes = [ |
||
| 35 | 'and', |
||
| 36 | 'delimiter-precedes-et-al', |
||
| 37 | 'delimiter-precedes-last', |
||
| 38 | 'et-al-min', |
||
| 39 | 'et-al-use-first', |
||
| 40 | 'et-al-use-last', |
||
| 41 | 'et-al-subsequent-min', |
||
| 42 | 'et-al-subsequent-use-first', |
||
| 43 | 'initialize', |
||
| 44 | 'initialize-with', |
||
| 45 | 'name-as-sort-order', |
||
| 46 | 'sort-separator' |
||
| 47 | ]; |
||
| 48 | |||
| 49 | /** |
||
| 50 | * @var bool |
||
| 51 | */ |
||
| 52 | protected $attributesInitialized = false; |
||
| 53 | |||
| 54 | /** |
||
| 55 | * Specifies the delimiter between the second to last and last name of the names in a name variable. Allowed values |
||
| 56 | * are “text” (selects the “and” term, e.g. “Doe, Johnson and Smith”) and “symbol” (selects the ampersand, |
||
| 57 | * e.g. “Doe, Johnson & Smith”). |
||
| 58 | * |
||
| 59 | * @var string |
||
| 60 | */ |
||
| 61 | private $and; |
||
| 62 | |||
| 63 | /** |
||
| 64 | * Determines when the name delimiter or a space is used between a truncated name list and the “et-al” |
||
| 65 | * (or “and others”) term in case of et-al abbreviation. Allowed values: |
||
| 66 | * - “contextual” - (default), name delimiter is only used for name lists truncated to two or more names |
||
| 67 | * - 1 name: “J. Doe et al.” |
||
| 68 | * - 2 names: “J. Doe, S. Smith, et al.” |
||
| 69 | * - “after-inverted-name” - name delimiter is only used if the preceding name is inverted as a result of the |
||
| 70 | * - name-as-sort-order attribute. E.g. with name-as-sort-order set to “first”: |
||
| 71 | * - “Doe, J., et al.” |
||
| 72 | * - “Doe, J., S. Smith et al.” |
||
| 73 | * - “always” - name delimiter is always used |
||
| 74 | * - 1 name: “J. Doe, et al.” |
||
| 75 | * - 2 names: “J. Doe, S. Smith, et al.” |
||
| 76 | * - “never” - name delimiter is never used |
||
| 77 | * - 1 name: “J. Doe et al.” |
||
| 78 | * - 2 names: “J. Doe, S. Smith et al.” |
||
| 79 | * |
||
| 80 | * @var string |
||
| 81 | */ |
||
| 82 | private $delimiterPrecedesEtAl; |
||
| 83 | |||
| 84 | /** |
||
| 85 | * Determines when the name delimiter is used to separate the second to last and the last name in name lists (if |
||
| 86 | * and is not set, the name delimiter is always used, regardless of the value of delimiter-precedes-last). Allowed |
||
| 87 | * values: |
||
| 88 | * |
||
| 89 | * - “contextual” - (default), name delimiter is only used for name lists with three or more names |
||
| 90 | * - 2 names: “J. Doe and T. Williams” |
||
| 91 | * - 3 names: “J. Doe, S. Smith, and T. Williams” |
||
| 92 | * - “after-inverted-name” - name delimiter is only used if the preceding name is inverted as a result of the |
||
| 93 | * name-as-sort-order attribute. E.g. with name-as-sort-order set to “first”: |
||
| 94 | * - “Doe, J., and T. Williams” |
||
| 95 | * - “Doe, J., S. Smith and T. Williams” |
||
| 96 | * - “always” - name delimiter is always used |
||
| 97 | * - 2 names: “J. Doe, and T. Williams” |
||
| 98 | * - 3 names: “J. Doe, S. Smith, and T. Williams” |
||
| 99 | * - “never” - name delimiter is never used |
||
| 100 | * - 2 names: “J. Doe and T. Williams” |
||
| 101 | * - 3 names: “J. Doe, S. Smith and T. Williams” |
||
| 102 | * |
||
| 103 | * @var string |
||
| 104 | */ |
||
| 105 | private $delimiterPrecedesLast; |
||
| 106 | |||
| 107 | /** |
||
| 108 | * Use of etAlMin (et-al-min attribute) and etAlUseFirst (et-al-use-first attribute) enables et-al abbreviation. If |
||
| 109 | * the number of names in a name variable matches or exceeds the number set on etAlMin, the rendered name list is |
||
| 110 | * truncated after reaching the number of names set on etAlUseFirst. |
||
| 111 | * |
||
| 112 | * @var int |
||
| 113 | */ |
||
| 114 | private $etAlMin; |
||
| 115 | |||
| 116 | /** |
||
| 117 | * Use of etAlMin (et-al-min attribute) and etAlUseFirst (et-al-use-first attribute) enables et-al abbreviation. If |
||
| 118 | * the number of names in a name variable matches or exceeds the number set on etAlMin, the rendered name list is |
||
| 119 | * truncated after reaching the number of names set on etAlUseFirst. |
||
| 120 | * |
||
| 121 | * @var int |
||
| 122 | */ |
||
| 123 | private $etAlUseFirst; |
||
| 124 | |||
| 125 | /** |
||
| 126 | * When set to “true” (the default is “false”), name lists truncated by et-al abbreviation are followed by the name |
||
| 127 | * delimiter, the ellipsis character, and the last name of the original name list. This is only possible when the |
||
| 128 | * original name list has at least two more names than the truncated name list (for this the value of |
||
| 129 | * et-al-use-first/et-al-subsequent-min must be at least 2 less than the value of |
||
| 130 | * et-al-min/et-al-subsequent-use-first). |
||
| 131 | * |
||
| 132 | * @var bool |
||
| 133 | */ |
||
| 134 | private $etAlUseLast = false; |
||
| 135 | |||
| 136 | /** |
||
| 137 | * If used, the values of these attributes (et-al-subsequent-min and et-al-subsequent-use-first) replace those of |
||
| 138 | * respectively et-al-min and et-al-use-first for subsequent cites (cites referencing earlier cited items). |
||
| 139 | * |
||
| 140 | * @var int |
||
| 141 | */ |
||
| 142 | private $etAlSubsequentMin; |
||
| 143 | |||
| 144 | /** |
||
| 145 | * If used, the values of these attributes (et-al-subsequent-min and et-al-subsequent-use-first) replace those of |
||
| 146 | * respectively et-al-min and et-al-use-first for subsequent cites (cites referencing earlier cited items). |
||
| 147 | * |
||
| 148 | * @var int |
||
| 149 | */ |
||
| 150 | private $etAlSubsequentUseFirst; |
||
| 151 | |||
| 152 | /** |
||
| 153 | * When set to “false” (the default is “true”), given names are no longer initialized when “initialize-with” is set. |
||
| 154 | * However, the value of “initialize-with” is still added after initials present in the full name (e.g. with |
||
| 155 | * initialize set to “false”, and initialize-with set to ”.”, “James T Kirk” becomes “James T. Kirk”). |
||
| 156 | * |
||
| 157 | * @var bool |
||
| 158 | */ |
||
| 159 | private $initialize = true; |
||
| 160 | |||
| 161 | /** |
||
| 162 | * When set, given names are converted to initials. The attribute value is added after each initial (”.” results |
||
| 163 | * in “J.J. Doe”). For compound given names (e.g. “Jean-Luc”), hyphenation of the initials can be controlled with |
||
| 164 | * the global initialize-with-hyphen option |
||
| 165 | * |
||
| 166 | * @var string |
||
| 167 | */ |
||
| 168 | private $initializeWith = ""; |
||
| 169 | |||
| 170 | /** |
||
| 171 | * Specifies that names should be displayed with the given name following the family name (e.g. “John Doe” becomes |
||
| 172 | * “Doe, John”). The attribute has two possible values: |
||
| 173 | * - “first” - attribute only has an effect on the first name of each name variable |
||
| 174 | * - “all” - attribute has an effect on all names |
||
| 175 | * Note that even when name-as-sort-order changes the name-part order, the display order is not necessarily the same |
||
| 176 | * as the sorting order for names containing particles and suffixes (see Name-part order). Also, name-as-sort-order |
||
| 177 | * only affects names written in the latin or Cyrillic alphabets. Names written in other alphabets (e.g. Asian |
||
| 178 | * scripts) are always displayed with the family name preceding the given name. |
||
| 179 | * |
||
| 180 | * @var string |
||
| 181 | */ |
||
| 182 | private $nameAsSortOrder = ""; |
||
| 183 | |||
| 184 | /** |
||
| 185 | * Sets the delimiter for name-parts that have switched positions as a result of name-as-sort-order. The default |
||
| 186 | * value is ”, ” (“Doe, John”). As is the case for name-as-sort-order, this attribute only affects names written in |
||
| 187 | * the latin or Cyrillic alphabets. |
||
| 188 | * |
||
| 189 | * @var string |
||
| 190 | */ |
||
| 191 | private $sortSeparator = ", "; |
||
| 192 | |||
| 193 | |||
| 194 | public function initInheritableNameAttributes(\SimpleXMLElement $node) |
||
| 304 | |||
| 305 | /** |
||
| 306 | * @return string |
||
| 307 | */ |
||
| 308 | public function getAnd() |
||
| 312 | |||
| 313 | /** |
||
| 314 | * @param string $and |
||
| 315 | */ |
||
| 316 | public function setAnd($and) |
||
| 320 | |||
| 321 | /** |
||
| 322 | * @return string |
||
| 323 | */ |
||
| 324 | public function getDelimiterPrecedesEtAl() |
||
| 328 | |||
| 329 | /** |
||
| 330 | * @param string $delimiterPrecedesEtAl |
||
| 331 | */ |
||
| 332 | public function setDelimiterPrecedesEtAl($delimiterPrecedesEtAl) |
||
| 336 | |||
| 337 | /** |
||
| 338 | * @return string |
||
| 339 | */ |
||
| 340 | public function getDelimiterPrecedesLast() |
||
| 344 | |||
| 345 | /** |
||
| 346 | * @param string $delimiterPrecedesLast |
||
| 347 | */ |
||
| 348 | public function setDelimiterPrecedesLast($delimiterPrecedesLast) |
||
| 352 | |||
| 353 | /** |
||
| 354 | * @return int |
||
| 355 | */ |
||
| 356 | public function getEtAlMin() |
||
| 360 | |||
| 361 | /** |
||
| 362 | * @param int $etAlMin |
||
| 363 | */ |
||
| 364 | public function setEtAlMin($etAlMin) |
||
| 368 | |||
| 369 | /** |
||
| 370 | * @return int |
||
| 371 | */ |
||
| 372 | public function getEtAlUseFirst() |
||
| 376 | |||
| 377 | /** |
||
| 378 | * @param int $etAlUseFirst |
||
| 379 | */ |
||
| 380 | public function setEtAlUseFirst($etAlUseFirst) |
||
| 384 | |||
| 385 | /** |
||
| 386 | * @return bool |
||
| 387 | */ |
||
| 388 | public function getEtAlUseLast() |
||
| 392 | |||
| 393 | /** |
||
| 394 | * @param bool $etAlUseLast |
||
| 395 | */ |
||
| 396 | public function setEtAlUseLast($etAlUseLast) |
||
| 400 | |||
| 401 | /** |
||
| 402 | * @return int |
||
| 403 | */ |
||
| 404 | public function getEtAlSubsequentMin() |
||
| 408 | |||
| 409 | /** |
||
| 410 | * @param int $etAlSubsequentMin |
||
| 411 | */ |
||
| 412 | public function setEtAlSubsequentMin($etAlSubsequentMin) |
||
| 416 | |||
| 417 | /** |
||
| 418 | * @return int |
||
| 419 | */ |
||
| 420 | public function getEtAlSubsequentUseFirst() |
||
| 424 | |||
| 425 | /** |
||
| 426 | * @param int $etAlSubsequentUseFirst |
||
| 427 | */ |
||
| 428 | public function setEtAlSubsequentUseFirst($etAlSubsequentUseFirst) |
||
| 432 | |||
| 433 | /** |
||
| 434 | * @return bool |
||
| 435 | */ |
||
| 436 | public function getInitialize() |
||
| 440 | |||
| 441 | /** |
||
| 442 | * @param bool $initialize |
||
| 443 | */ |
||
| 444 | public function setInitialize($initialize) |
||
| 448 | |||
| 449 | /** |
||
| 450 | * @return string |
||
| 451 | */ |
||
| 452 | public function getInitializeWith() |
||
| 456 | |||
| 457 | /** |
||
| 458 | * @param string $initializeWith |
||
| 459 | */ |
||
| 460 | public function setInitializeWith($initializeWith) |
||
| 464 | |||
| 465 | /** |
||
| 466 | * @return string |
||
| 467 | */ |
||
| 468 | public function getNameAsSortOrder() |
||
| 472 | |||
| 473 | /** |
||
| 474 | * @param string $nameAsSortOrder |
||
| 475 | */ |
||
| 476 | public function setNameAsSortOrder($nameAsSortOrder) |
||
| 480 | |||
| 481 | /** |
||
| 482 | * @return string |
||
| 483 | */ |
||
| 484 | public function getSortSeparator() |
||
| 488 | |||
| 489 | /** |
||
| 490 | * @param string $sortSeparator |
||
| 491 | */ |
||
| 492 | public function setSortSeparator($sortSeparator) |
||
| 496 | |||
| 497 | } |
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.