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 GridService 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 GridService, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 22 | class GridService extends AbstractTca |
||
| 23 | { |
||
| 24 | |||
| 25 | /** |
||
| 26 | * @var array |
||
| 27 | */ |
||
| 28 | protected $tca; |
||
| 29 | |||
| 30 | /** |
||
| 31 | * @var string |
||
| 32 | */ |
||
| 33 | protected $tableName; |
||
| 34 | |||
| 35 | /** |
||
| 36 | * All fields available in the Grid. |
||
| 37 | * |
||
| 38 | * @var array |
||
| 39 | */ |
||
| 40 | protected $fields; |
||
| 41 | |||
| 42 | /** |
||
| 43 | * All fields regardless whether they have been excluded or not. |
||
| 44 | * |
||
| 45 | * @var array |
||
| 46 | */ |
||
| 47 | protected $allFields; |
||
| 48 | |||
| 49 | /** |
||
| 50 | * @var array |
||
| 51 | */ |
||
| 52 | protected $instances; |
||
| 53 | |||
| 54 | /** |
||
| 55 | * @var array |
||
| 56 | */ |
||
| 57 | protected $facets; |
||
| 58 | |||
| 59 | /** |
||
| 60 | * __construct |
||
| 61 | * |
||
| 62 | * @throws InvalidKeyInArrayException |
||
| 63 | * @param string $tableName |
||
| 64 | */ |
||
| 65 | public function __construct($tableName) |
||
| 76 | |||
| 77 | /** |
||
| 78 | * Returns an array containing column names. |
||
| 79 | * |
||
| 80 | * @return array |
||
| 81 | */ |
||
| 82 | public function getFieldNames() |
||
| 87 | |||
| 88 | /** |
||
| 89 | * Returns an array containing column names. |
||
| 90 | * |
||
| 91 | * @return array |
||
| 92 | */ |
||
| 93 | public function getAllFieldNames() |
||
| 98 | |||
| 99 | /** |
||
| 100 | * Get the label key. |
||
| 101 | * |
||
| 102 | * @param string $fieldNameAndPath |
||
| 103 | * @return string |
||
| 104 | * @throws \Fab\Vidi\Exception\InvalidKeyInArrayException |
||
| 105 | */ |
||
| 106 | public function getLabelKey($fieldNameAndPath) |
||
| 130 | |||
| 131 | /** |
||
| 132 | * Get the translation of a label given a column name. |
||
| 133 | * |
||
| 134 | * @param string $fieldNameAndPath |
||
| 135 | * @return string |
||
| 136 | */ |
||
| 137 | public function getLabel($fieldNameAndPath) |
||
| 163 | |||
| 164 | /** |
||
| 165 | * Returns the field name given its position. |
||
| 166 | * |
||
| 167 | * @param string $position the position of the field in the grid |
||
| 168 | * @throws InvalidKeyInArrayException |
||
| 169 | * @return int |
||
| 170 | */ |
||
| 171 | public function getFieldNameByPosition($position) |
||
| 180 | |||
| 181 | /** |
||
| 182 | * Returns a field name. |
||
| 183 | * |
||
| 184 | * @param string $fieldName |
||
| 185 | * @return array |
||
| 186 | * @throws InvalidKeyInArrayException |
||
| 187 | */ |
||
| 188 | public function getField($fieldName) |
||
| 193 | |||
| 194 | /** |
||
| 195 | * Returns an array containing column names for the Grid. |
||
| 196 | * |
||
| 197 | * @return array |
||
| 198 | * @throws \Exception |
||
| 199 | */ |
||
| 200 | public function getFields() |
||
| 221 | |||
| 222 | /** |
||
| 223 | * Remove fields according to Grid configuration. |
||
| 224 | * |
||
| 225 | * @param $fields |
||
| 226 | * @return array |
||
| 227 | */ |
||
| 228 | protected function filterByIncludedFields($fields) |
||
| 243 | |||
| 244 | /** |
||
| 245 | * Remove fields according to BE User permission. |
||
| 246 | * |
||
| 247 | * @param $fields |
||
| 248 | * @return array |
||
| 249 | * @throws \Exception |
||
| 250 | */ |
||
| 251 | View Code Duplication | protected function filterByBackendUser($fields) |
|
| 262 | |||
| 263 | /** |
||
| 264 | * Remove fields according to Grid configuration. |
||
| 265 | * |
||
| 266 | * @param $fields |
||
| 267 | * @return array |
||
| 268 | */ |
||
| 269 | protected function filterByExcludedFields($fields) |
||
| 281 | |||
| 282 | /** |
||
| 283 | * Returns an array containing column names for the Grid. |
||
| 284 | * |
||
| 285 | * @return array |
||
| 286 | */ |
||
| 287 | public function getAllFields() |
||
| 338 | |||
| 339 | /** |
||
| 340 | * Tell whether the field exists in the grid or not. |
||
| 341 | * |
||
| 342 | * @param string $fieldName |
||
| 343 | * @return bool |
||
| 344 | */ |
||
| 345 | public function hasField($fieldName) |
||
| 350 | |||
| 351 | /** |
||
| 352 | * Tell whether the facet exists in the grid or not. |
||
| 353 | * |
||
| 354 | * @param string $facetName |
||
| 355 | * @return bool |
||
| 356 | */ |
||
| 357 | public function hasFacet($facetName) |
||
| 362 | |||
| 363 | /** |
||
| 364 | * Returns an array containing facets fields. |
||
| 365 | * |
||
| 366 | * @return FacetInterface[] |
||
| 367 | */ |
||
| 368 | public function getFacets() |
||
| 399 | |||
| 400 | /** |
||
| 401 | * Returns the "sortable" value of the column. |
||
| 402 | * |
||
| 403 | * @param string $fieldName |
||
| 404 | * @return int|string |
||
| 405 | */ |
||
| 406 | public function isSortable($fieldName) |
||
| 417 | |||
| 418 | /** |
||
| 419 | * Returns the "canBeHidden" value of the column. |
||
| 420 | * |
||
| 421 | * @param string $fieldName |
||
| 422 | * @return bool |
||
| 423 | */ |
||
| 424 | public function canBeHidden($fieldName) |
||
| 429 | |||
| 430 | /** |
||
| 431 | * Returns the "width" value of the column. |
||
| 432 | * |
||
| 433 | * @param string $fieldName |
||
| 434 | * @return int|string |
||
| 435 | */ |
||
| 436 | public function getWidth($fieldName) |
||
| 441 | |||
| 442 | /** |
||
| 443 | * Returns the "visible" value of the column. |
||
| 444 | * |
||
| 445 | * @param string $fieldName |
||
| 446 | * @return bool |
||
| 447 | */ |
||
| 448 | public function isVisible($fieldName) |
||
| 453 | |||
| 454 | /** |
||
| 455 | * Returns the "editable" value of the column. |
||
| 456 | * |
||
| 457 | * @param string $columnName |
||
| 458 | * @return bool |
||
| 459 | */ |
||
| 460 | public function isEditable($columnName) |
||
| 465 | |||
| 466 | /** |
||
| 467 | * Returns the "localized" value of the column. |
||
| 468 | * |
||
| 469 | * @param string $columnName |
||
| 470 | * @return bool |
||
| 471 | */ |
||
| 472 | public function isLocalized($columnName) |
||
| 477 | |||
| 478 | /** |
||
| 479 | * |
||
| 480 | * Returns the "html" value of the column. |
||
| 481 | * |
||
| 482 | * @param string $fieldName |
||
| 483 | * @return string |
||
| 484 | */ |
||
| 485 | public function getHeader($fieldName) |
||
| 490 | |||
| 491 | /** |
||
| 492 | * Fetch a possible from a Grid Renderer. If no value is found, returns null |
||
| 493 | * |
||
| 494 | * @param string $fieldName |
||
| 495 | * @param string $key |
||
| 496 | * @param mixed $defaultValue |
||
| 497 | * @return null|mixed |
||
| 498 | */ |
||
| 499 | public function get($fieldName, $key, $defaultValue = null) |
||
| 516 | |||
| 517 | /** |
||
| 518 | * Returns whether the column has a renderer. |
||
| 519 | * |
||
| 520 | * @param string $fieldName |
||
| 521 | * @return bool |
||
| 522 | */ |
||
| 523 | public function hasRenderers($fieldName) |
||
| 528 | |||
| 529 | /** |
||
| 530 | * Returns a renderer. |
||
| 531 | * |
||
| 532 | * @param string $fieldName |
||
| 533 | * @return array |
||
| 534 | */ |
||
| 535 | public function getRenderers($fieldName) |
||
| 550 | |||
| 551 | /** |
||
| 552 | * @param string $renderer |
||
| 553 | * @return array |
||
| 554 | */ |
||
| 555 | protected function convertRendererToArray($renderer, array $field) |
||
| 574 | |||
| 575 | /** |
||
| 576 | * Returns the class names applied to a cell |
||
| 577 | * |
||
| 578 | * @param string $fieldName |
||
| 579 | * @return bool |
||
| 580 | */ |
||
| 581 | public function getClass($fieldName) |
||
| 586 | |||
| 587 | /** |
||
| 588 | * Returns whether the column has a label. |
||
| 589 | * |
||
| 590 | * @param string $fieldNameAndPath |
||
| 591 | * @return bool |
||
| 592 | */ |
||
| 593 | public function hasLabel($fieldNameAndPath) |
||
| 611 | |||
| 612 | /** |
||
| 613 | * @return array |
||
| 614 | */ |
||
| 615 | public function getTca() |
||
| 619 | |||
| 620 | /** |
||
| 621 | * @return array |
||
| 622 | */ |
||
| 623 | public function getIncludedFields() |
||
| 627 | |||
| 628 | /** |
||
| 629 | * Return excluded fields from configuration + preferences. |
||
| 630 | * |
||
| 631 | * @return array |
||
| 632 | */ |
||
| 633 | public function getExcludedFields() |
||
| 640 | |||
| 641 | /** |
||
| 642 | * Fetch excluded fields from configuration. |
||
| 643 | * |
||
| 644 | * @return array |
||
| 645 | */ |
||
| 646 | protected function getExcludedFieldsFromConfiguration() |
||
| 657 | |||
| 658 | /** |
||
| 659 | * Fetch excluded fields from preferences. |
||
| 660 | * |
||
| 661 | * @return array |
||
| 662 | */ |
||
| 663 | protected function getExcludedFieldsFromPreferences() |
||
| 668 | |||
| 669 | /** |
||
| 670 | * @return array |
||
| 671 | */ |
||
| 672 | public function areFilesIncludedInExport() |
||
| 681 | |||
| 682 | /** |
||
| 683 | * Returns a "facet" service instance. |
||
| 684 | * |
||
| 685 | * @param string|FacetInterface $facetName |
||
| 686 | * @return StandardFacet |
||
| 687 | */ |
||
| 688 | protected function instantiateStandardFacet($facetName) |
||
| 700 | |||
| 701 | /** |
||
| 702 | * Returns a "facet" service instance. |
||
| 703 | * |
||
| 704 | * @param string|FacetInterface $facetName |
||
| 705 | * @return FacetInterface |
||
| 706 | */ |
||
| 707 | public function facet($facetName = '') |
||
| 712 | |||
| 713 | /** |
||
| 714 | * @return \Fab\Vidi\Resolver\FieldPathResolver|object |
||
| 715 | */ |
||
| 716 | protected function getFieldPathResolver() |
||
| 720 | |||
| 721 | /** |
||
| 722 | * @return ModulePreferences|object |
||
| 723 | */ |
||
| 724 | protected function getModulePreferences() |
||
| 728 | |||
| 729 | /** |
||
| 730 | * @return \TYPO3\CMS\Lang\LanguageService|object |
||
| 731 | * @throws \InvalidArgumentException |
||
| 732 | */ |
||
| 733 | protected function getLanguageService() |
||
| 737 | |||
| 738 | } |
||
| 739 |
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.