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 NorthWindDSExpressionProvider 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 NorthWindDSExpressionProvider, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
12 | class NorthWindDSExpressionProvider implements IExpressionProvider |
||
|
|||
13 | { |
||
14 | const ADD = '+'; |
||
15 | const CLOSE_BRACKET = ')'; |
||
16 | const COMMA = ','; |
||
17 | const DIVIDE = '/'; |
||
18 | const SUBTRACT = '-'; |
||
19 | const EQUAL = '='; |
||
20 | const GREATERTHAN = '>'; |
||
21 | const GREATERTHAN_OR_EQUAL = '>='; |
||
22 | const LESSTHAN = '<'; |
||
23 | const LESSTHAN_OR_EQUAL = '<='; |
||
24 | const LOGICAL_AND = 'AND'; |
||
25 | const LOGICAL_NOT = 'not'; |
||
26 | const LOGICAL_OR = 'OR'; |
||
27 | const MEMBERACCESS = ''; |
||
28 | const MODULO = '%'; |
||
29 | const MULTIPLY = '*'; |
||
30 | const NEGATE = '-'; |
||
31 | const NOTEQUAL = '!='; |
||
32 | const OPEN_BRAKET = '('; |
||
33 | // The default parameter for ROUND sql function-call |
||
34 | private $_default_round = 0; |
||
35 | |||
36 | /** |
||
37 | * The name of iterator |
||
38 | * |
||
39 | * @var string |
||
40 | */ |
||
41 | private $_iterName; |
||
42 | |||
43 | /** |
||
44 | * The type of the resource pointed by the resource path segement |
||
45 | * |
||
46 | * @var ResourceType |
||
47 | */ |
||
48 | private $_resourceType; |
||
49 | |||
50 | /** |
||
51 | * Constructs new instance of SQLSrverExpressionProvider for NorthWind DB |
||
52 | * |
||
53 | * @param string $iterName The name of the iterator |
||
54 | */ |
||
55 | public function __construct() |
||
58 | |||
59 | /** |
||
60 | * Get the name of the iterator |
||
61 | * |
||
62 | * @return string |
||
63 | */ |
||
64 | public function getIteratorName() |
||
68 | |||
69 | /** |
||
70 | * call-back for setting the resource type. |
||
71 | * |
||
72 | * @param ResourceType $resourceType The resource type on which the filter |
||
73 | * is going to be applied. |
||
74 | */ |
||
75 | public function setResourceType(ResourceType $resourceType) |
||
79 | |||
80 | /** |
||
81 | * Call-back for logical expression |
||
82 | * |
||
83 | * @param ExpressionType $expressionType The type of logical expression. |
||
84 | * @param string $left The left expression. |
||
85 | * @param string $right The left expression. |
||
86 | * |
||
87 | * @return string |
||
88 | */ |
||
89 | View Code Duplication | public function onLogicalExpression($expressionType, $left, $right) |
|
102 | |||
103 | /** |
||
104 | * Call-back for arithmetic expression |
||
105 | * |
||
106 | * @param ExpressionType $expressionType The type of arithmetic expression. |
||
107 | * @param string $left The left expression. |
||
108 | * @param string $right The left expression. |
||
109 | * |
||
110 | * @return string |
||
111 | */ |
||
112 | View Code Duplication | public function onArithmeticExpression($expressionType, $left, $right) |
|
134 | |||
135 | /** |
||
136 | * Call-back for relational expression |
||
137 | * |
||
138 | * @param ExpressionType $expressionType The type of relation expression |
||
139 | * @param string $left The left expression |
||
140 | * @param string $right The left expression |
||
141 | * |
||
142 | * @return string |
||
143 | */ |
||
144 | View Code Duplication | public function onRelationalExpression($expressionType, $left, $right) |
|
173 | |||
174 | /** |
||
175 | * Call-back for unary expression |
||
176 | * |
||
177 | * @param ExpressionType $expressionType The type of unary expression |
||
178 | * @param string $child The child expression |
||
179 | * |
||
180 | * @return string |
||
181 | */ |
||
182 | View Code Duplication | public function onUnaryExpression($expressionType, $child) |
|
195 | |||
196 | /** |
||
197 | * Call-back for constant expression |
||
198 | * |
||
199 | * @param IType $type The type of constant |
||
200 | * @param objetc $value The value of the constant |
||
201 | * |
||
202 | * @return string |
||
203 | */ |
||
204 | View Code Duplication | public function onConstantExpression(IType $type, $value) |
|
214 | |||
215 | /** |
||
216 | * Call-back for property access expression |
||
217 | * |
||
218 | * @param PropertyAccessExpression $expression The property access expression |
||
219 | * |
||
220 | * @return string |
||
221 | */ |
||
222 | public function onPropertyAccessExpression($expression) |
||
290 | /** |
||
291 | * Call-back for function call expression |
||
292 | * |
||
293 | * @param FunctionDescription $functionDescription Description of the function. |
||
294 | * @param array<string> $params Paameters to the function. |
||
295 | * |
||
296 | * @return string |
||
297 | */ |
||
298 | public function onFunctionCallExpression($functionDescription, $params) |
||
400 | |||
401 | /** |
||
402 | * To format binary expression |
||
403 | * |
||
404 | * @param string $operator The binary operator. |
||
405 | * @param string $left The left operand. |
||
406 | * @param string $right The right operand. |
||
407 | * |
||
408 | * @return string |
||
409 | */ |
||
410 | private function _prepareBinaryExpression($operator, $left, $right) |
||
464 | |||
465 | /** |
||
466 | * To format unary expression |
||
467 | * |
||
468 | * @param string $operator The unary operator. |
||
469 | * @param string $child The operand. |
||
470 | * |
||
471 | * @return string |
||
472 | */ |
||
473 | private function _prepareUnaryExpression($operator, $child) |
||
477 | } |
||
478 |
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.