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 ExprBuilder 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 ExprBuilder, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
21 | class ExprBuilder implements ExpressionInterface |
||
22 | { |
||
23 | /** |
||
24 | * @var ExpressionInterface $wrappedExpression |
||
25 | */ |
||
26 | private $wrappedExpression; |
||
27 | |||
28 | /** |
||
29 | * ExprBuilder constructor. |
||
30 | */ |
||
31 | public function __construct() |
||
35 | /** |
||
36 | * @param mixed $expression |
||
37 | * |
||
38 | * @return ExpressionInterface |
||
39 | */ |
||
40 | public static function normalizeExpression($expression) |
||
70 | |||
71 | /** |
||
72 | * @return ExpressionInterface |
||
73 | */ |
||
74 | public function getWrappedExpression() |
||
78 | |||
79 | /** |
||
80 | * @inheritdoc |
||
81 | */ |
||
82 | public function compile() |
||
86 | |||
87 | /** |
||
88 | * @param mixed $alias |
||
89 | * |
||
90 | * @return ExprBuilder |
||
91 | */ |
||
92 | public function alias($alias) |
||
98 | |||
99 | /** |
||
100 | * @return ExprBuilder |
||
101 | */ |
||
102 | public function sumNullable() |
||
106 | |||
107 | /** |
||
108 | * @return ExprBuilder |
||
109 | */ |
||
110 | public function in() |
||
116 | |||
117 | /** |
||
118 | * @return ExprBuilder |
||
119 | */ |
||
120 | public function using() |
||
124 | |||
125 | /** |
||
126 | * @return ExprBuilder |
||
127 | */ |
||
128 | public function desc() |
||
132 | |||
133 | /** |
||
134 | * @return ExprBuilder |
||
135 | */ |
||
136 | public function asc() |
||
140 | |||
141 | ############################### |
||
142 | ### COMPARISION EXPRESSIONS ### |
||
143 | ############################### |
||
144 | |||
145 | /** |
||
146 | * @param mixed $from |
||
147 | * @param mixed $to |
||
148 | * |
||
149 | * @return ExprBuilder |
||
150 | */ |
||
151 | View Code Duplication | public function between($from, $to) |
|
158 | |||
159 | /** |
||
160 | * @param mixed $right |
||
161 | * |
||
162 | * @return ExprBuilder |
||
163 | */ |
||
164 | public function eq($right) |
||
170 | |||
171 | /** |
||
172 | * @param mixed $right |
||
173 | * |
||
174 | * @return ExprBuilder |
||
175 | */ |
||
176 | public function gt($right) |
||
182 | |||
183 | /** |
||
184 | * @param mixed $right |
||
185 | * |
||
186 | * @return ExprBuilder |
||
187 | */ |
||
188 | public function gte($right) |
||
194 | |||
195 | /** |
||
196 | * @return ExprBuilder |
||
197 | */ |
||
198 | public function isNull() |
||
202 | |||
203 | /** |
||
204 | * @param mixed $right |
||
205 | * |
||
206 | * @return ExprBuilder |
||
207 | */ |
||
208 | public function lt($right) |
||
214 | |||
215 | /** |
||
216 | * @param mixed $right |
||
217 | * |
||
218 | * @return ExprBuilder |
||
219 | */ |
||
220 | public function lte($right) |
||
226 | |||
227 | /** |
||
228 | * @param mixed $right |
||
229 | * |
||
230 | * @return ExprBuilder |
||
231 | */ |
||
232 | public function neq($right) |
||
238 | |||
239 | /** |
||
240 | * @param mixed $from |
||
241 | * @param mixed $to |
||
242 | * |
||
243 | * @return ExprBuilder |
||
244 | */ |
||
245 | View Code Duplication | public function notBetween($from, $to) |
|
252 | |||
253 | /** |
||
254 | * @param mixed $right |
||
255 | * |
||
256 | * @return ExprBuilder |
||
257 | */ |
||
258 | public function nullEq($right) |
||
264 | |||
265 | ############################## |
||
266 | ### ARITHMETIC EXPRESSIONS ### |
||
267 | ############################## |
||
268 | |||
269 | /** |
||
270 | * @param mixed $right |
||
271 | * |
||
272 | * @return ExprBuilder |
||
273 | */ |
||
274 | public function add($right) |
||
280 | |||
281 | /** |
||
282 | * @param mixed $right |
||
283 | * |
||
284 | * @return ExprBuilder |
||
285 | */ |
||
286 | public function div($right) |
||
292 | |||
293 | /** |
||
294 | * @param mixed $right |
||
295 | * |
||
296 | * @return ExprBuilder |
||
297 | */ |
||
298 | public function divide($right) |
||
304 | |||
305 | /** |
||
306 | * @param mixed $right |
||
307 | * |
||
308 | * @return ExprBuilder |
||
309 | */ |
||
310 | public function modulo($right) |
||
316 | |||
317 | /** |
||
318 | * @param mixed $right |
||
319 | * |
||
320 | * @return ExprBuilder |
||
321 | */ |
||
322 | public function multiply($right) |
||
328 | |||
329 | /** |
||
330 | * @param mixed $right |
||
331 | * |
||
332 | * @return ExprBuilder |
||
333 | */ |
||
334 | public function subtract($right) |
||
340 | |||
341 | ################# |
||
342 | ### FUNCTIONS ### |
||
343 | ################# |
||
344 | |||
345 | /** |
||
346 | * @return ExprBuilder |
||
347 | */ |
||
348 | public function asci() |
||
352 | |||
353 | /** |
||
354 | * @return ExprBuilder |
||
355 | */ |
||
356 | public function bin() |
||
360 | |||
361 | /** |
||
362 | * @return ExprBuilder |
||
363 | */ |
||
364 | public function bitLength() |
||
368 | |||
369 | /** |
||
370 | * @return ExprBuilder |
||
371 | */ |
||
372 | public function char() |
||
376 | |||
377 | /** |
||
378 | * @return ExprBuilder |
||
379 | */ |
||
380 | public function coalesce() |
||
384 | |||
385 | /** |
||
386 | * @return ExprBuilder |
||
387 | */ |
||
388 | public function concat() |
||
392 | |||
393 | /** |
||
394 | * @return ExprBuilder |
||
395 | */ |
||
396 | public function concatWs() |
||
400 | |||
401 | /** |
||
402 | * @return ExprBuilder |
||
403 | */ |
||
404 | public function elt() |
||
408 | |||
409 | /** |
||
410 | * @return ExprBuilder |
||
411 | */ |
||
412 | public function exportSet() |
||
416 | |||
417 | /** |
||
418 | * @return ExprBuilder |
||
419 | */ |
||
420 | public function field() |
||
424 | |||
425 | /** |
||
426 | * @param mixed $expression |
||
427 | * |
||
428 | * @return ExprBuilder |
||
429 | */ |
||
430 | public function ifNull($expression) |
||
436 | |||
437 | /** |
||
438 | * @return ExprBuilder |
||
439 | */ |
||
440 | public function max() |
||
444 | |||
445 | /** |
||
446 | * @return ExprBuilder |
||
447 | */ |
||
448 | public function sum() |
||
452 | |||
453 | /** |
||
454 | * @return ExprBuilder |
||
455 | */ |
||
456 | public function year() |
||
460 | } |
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.