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 FunctionDescription 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 FunctionDescription, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
34 | class FunctionDescription |
||
35 | { |
||
36 | /** |
||
37 | * @var string |
||
38 | */ |
||
39 | public $name; |
||
40 | |||
41 | /** |
||
42 | * @var IType |
||
43 | */ |
||
44 | public $returnType; |
||
45 | |||
46 | /** |
||
47 | * @var IType[] |
||
48 | */ |
||
49 | public $argumentTypes; |
||
50 | |||
51 | /** |
||
52 | * Create new instance of FunctionDescription |
||
53 | * |
||
54 | * @param string $name Name of the function |
||
55 | * @param IType $returnType Return type |
||
56 | * @param IType[] $argumentTypes Parameter type |
||
57 | */ |
||
58 | public function __construct($name, $returnType, $argumentTypes) |
||
64 | |||
65 | /** |
||
66 | * Get the function prototype as string |
||
67 | * |
||
68 | * @return string |
||
69 | */ |
||
70 | public function getPrototypeAsString() |
||
80 | |||
81 | /** |
||
82 | * Create function descriptions for supported function-calls in $filter option |
||
83 | * |
||
84 | * TODO: FIGURE OUT WHAT THE HECK THIS IS RETURNING!?!? |
||
85 | * |
||
86 | * @return array indexed by function name |
||
87 | */ |
||
88 | public static function filterFunctionDescriptions() |
||
254 | |||
255 | /** |
||
256 | * Get function description for string comparison |
||
257 | * |
||
258 | * @return \POData\UriProcessor\QueryProcessor\FunctionDescription[] |
||
259 | */ |
||
260 | public static function stringComparisonFunctions() |
||
269 | |||
270 | /** |
||
271 | * Get function description for datetime comparison |
||
272 | * |
||
273 | * @return \POData\UriProcessor\QueryProcessor\FunctionDescription[] |
||
274 | */ |
||
275 | public static function dateTimeComparisonFunctions() |
||
284 | |||
285 | /** |
||
286 | * Get function description for guid equality check |
||
287 | * |
||
288 | * @return \POData\UriProcessor\QueryProcessor\FunctionDescription[] |
||
289 | */ |
||
290 | public static function guidEqualityFunctions() |
||
299 | |||
300 | /** |
||
301 | * Get function description for binary equality check |
||
302 | * |
||
303 | * @return \POData\UriProcessor\QueryProcessor\FunctionDescription[] |
||
304 | */ |
||
305 | public static function binaryEqualityFunctions() |
||
314 | |||
315 | /** |
||
316 | * Get function descriptions for arithmetic operations |
||
317 | * |
||
318 | * @return \POData\UriProcessor\QueryProcessor\FunctionDescription[] |
||
319 | */ |
||
320 | public static function arithmeticOperationFunctions() |
||
349 | |||
350 | /** |
||
351 | * Get function descriptions for arithmetic add operations |
||
352 | * |
||
353 | * @return \POData\UriProcessor\QueryProcessor\FunctionDescription[] indexed by function name |
||
354 | */ |
||
355 | public static function addOperationFunctions() |
||
359 | |||
360 | /** |
||
361 | * Get function descriptions for arithmetic subtract operations |
||
362 | * |
||
363 | * @return \POData\UriProcessor\QueryProcessor\FunctionDescription[] indexed by function name |
||
364 | */ |
||
365 | public static function subtractOperationFunctions() |
||
369 | |||
370 | /** |
||
371 | * Get function descriptions for logical operations |
||
372 | * |
||
373 | * @return \POData\UriProcessor\QueryProcessor\FunctionDescription[] |
||
374 | */ |
||
375 | public static function logicalOperationFunctions() |
||
384 | |||
385 | /** |
||
386 | * Get function descriptions for relational operations |
||
387 | * |
||
388 | * @return \POData\UriProcessor\QueryProcessor\FunctionDescription[] |
||
389 | */ |
||
390 | public static function relationalOperationFunctions() |
||
414 | |||
415 | /** |
||
416 | * Get function descriptions for unary not operation |
||
417 | * |
||
418 | * @return \POData\UriProcessor\QueryProcessor\FunctionDescription[] |
||
419 | */ |
||
420 | public static function notOperationFunctions() |
||
429 | |||
430 | /** |
||
431 | * Get function description for checking an operand is null or not |
||
432 | * |
||
433 | * @param IType $type Type of the argument to null check function. |
||
434 | * |
||
435 | * @return \POData\UriProcessor\QueryProcessor\FunctionDescription |
||
436 | */ |
||
437 | public static function isNullCheckFunction(IType $type) |
||
441 | |||
442 | /** |
||
443 | * Get function description for unary negate operator |
||
444 | * |
||
445 | * @return \POData\UriProcessor\QueryProcessor\FunctionDescription[] |
||
446 | */ |
||
447 | public static function negateOperationFunctions() |
||
458 | |||
459 | /** |
||
460 | * To throw ODataException for incompatible types |
||
461 | * |
||
462 | * @param ExpressionToken $expressionToken Expression token |
||
463 | * @param AbstractExpression[] $argExpressions Array of argument expression |
||
464 | * |
||
465 | * @throws ODataException |
||
466 | * @return void |
||
467 | */ |
||
468 | public static function incompatibleError($expressionToken, $argExpressions) |
||
488 | |||
489 | /** |
||
490 | * Validate operands of an arithmetic operation and promote if required |
||
491 | * |
||
492 | * @param ExpressionToken $expressionToken The expression token |
||
493 | * @param AbstractExpression $leftArgument The left expression |
||
494 | * @param AbstractExpression $rightArgument The right expression |
||
495 | * |
||
496 | * @return IType |
||
497 | */ |
||
498 | View Code Duplication | public static function verifyAndPromoteArithmeticOpArguments($expressionToken, |
|
514 | |||
515 | /** |
||
516 | * Validate operands of an logical operation |
||
517 | * |
||
518 | * @param ExpressionToken $expressionToken The expression token |
||
519 | * @param AbstractExpression $leftArgument The left expression |
||
520 | * @param AbstractExpression $rightArgument The right expression |
||
521 | * |
||
522 | * @return void |
||
523 | * |
||
524 | * @throws ODataException |
||
525 | */ |
||
526 | View Code Duplication | public static function verifyLogicalOpArguments($expressionToken, |
|
540 | |||
541 | /** |
||
542 | * Validate operands of an relational operation |
||
543 | * |
||
544 | * @param ExpressionToken $expressionToken The expression token |
||
545 | * @param AbstractExpression $leftArgument The left argument expression |
||
546 | * @param AbstractExpression $rightArgument The right argument expression |
||
547 | * |
||
548 | * @return void |
||
549 | */ |
||
550 | public static function verifyRelationalOpArguments($expressionToken, |
||
619 | |||
620 | /** |
||
621 | * Validate operands of a unary operation |
||
622 | * |
||
623 | * @param ExpressionToken $expressionToken The expression token |
||
624 | * @param AbstractExpression $argExpression Argument expression |
||
625 | * |
||
626 | * @throws ODataException |
||
627 | * |
||
628 | * @return void |
||
629 | */ |
||
630 | public static function validateUnaryOpArguments($expressionToken, $argExpression) |
||
652 | |||
653 | /** |
||
654 | * Check am identifier is a valid filter function |
||
655 | * |
||
656 | * @param ExpressionToken $expressionToken The expression token |
||
657 | * |
||
658 | * @throws ODataException |
||
659 | * |
||
660 | * @return \POData\UriProcessor\QueryProcessor\FunctionDescription[] Array of matching functions |
||
661 | */ |
||
662 | public static function verifyFunctionExists($expressionToken) |
||
677 | |||
678 | /** |
||
679 | * Validate operands (arguments) of a function call operation and return |
||
680 | * matching function |
||
681 | * |
||
682 | * @param \POData\UriProcessor\QueryProcessor\FunctionDescription[] $functions List of functions to be checked |
||
683 | * @param AbstractExpression[] $argExpressions Function argument expressions |
||
684 | * @param ExpressionToken $expressionToken Expression token |
||
685 | * |
||
686 | * @throws ODataException |
||
687 | * |
||
688 | * @return \POData\UriProcessor\QueryProcessor\FunctionDescription |
||
689 | */ |
||
690 | public static function verifyFunctionCallOpArguments($functions, |
||
712 | |||
713 | /** |
||
714 | * Finds a function from the list of functions whose argument types matches |
||
715 | * with types of expressions |
||
716 | * |
||
717 | * @param \POData\UriProcessor\QueryProcessor\FunctionDescription[] $functionDescriptions List of functions |
||
718 | * @param AbstractExpression[] $argExpressions Function argument expressions |
||
719 | * @param Boolean $promoteArguments Function argument |
||
720 | * |
||
721 | * @return \POData\UriProcessor\QueryProcessor\FunctionDescription|null Reference to the matching function if |
||
722 | * found else NULL |
||
723 | */ |
||
724 | public static function findFunctionWithPromotion($functionDescriptions, |
||
784 | } |
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.