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 OracleGrammar 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 OracleGrammar, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
11 | class OracleGrammar extends Grammar |
||
12 | { |
||
13 | use OracleReservedWords; |
||
14 | |||
15 | /** |
||
16 | * The keyword identifier wrapper format. |
||
17 | * |
||
18 | * @var string |
||
19 | */ |
||
20 | protected $wrapper = '%s'; |
||
21 | |||
22 | /** |
||
23 | * The possible column modifiers. |
||
24 | * |
||
25 | * @var array |
||
26 | */ |
||
27 | protected $modifiers = ['Increment', 'Nullable', 'Default']; |
||
28 | |||
29 | /** |
||
30 | * The possible column serials |
||
31 | * |
||
32 | * @var array |
||
33 | */ |
||
34 | protected $serials = ['bigInteger', 'integer', 'mediumInteger', 'smallInteger', 'tinyInteger']; |
||
35 | |||
36 | /** |
||
37 | * Compile a create table command. |
||
38 | * |
||
39 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
40 | * @param \Illuminate\Support\Fluent $command |
||
41 | * @return string |
||
42 | */ |
||
43 | public function compileCreate(Blueprint $blueprint, Fluent $command) |
||
63 | |||
64 | /** |
||
65 | * Get the foreign key syntax for a table creation statement. |
||
66 | * |
||
67 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
68 | * @return string |
||
69 | */ |
||
70 | protected function addForeignKeys(Blueprint $blueprint) |
||
98 | |||
99 | /** |
||
100 | * Get the primary key syntax for a table creation statement. |
||
101 | * |
||
102 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
103 | * @return string|null |
||
104 | */ |
||
105 | protected function addPrimaryKeys(Blueprint $blueprint) |
||
117 | |||
118 | /** |
||
119 | * Compile the query to determine if a table exists. |
||
120 | * |
||
121 | * @return string |
||
122 | */ |
||
123 | public function compileTableExists() |
||
127 | |||
128 | /** |
||
129 | * Compile the query to determine the list of columns. |
||
130 | * |
||
131 | * @return string |
||
132 | */ |
||
133 | public function compileColumnExists() |
||
137 | |||
138 | /** |
||
139 | * Compile an add column command. |
||
140 | * |
||
141 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
142 | * @param \Illuminate\Support\Fluent $command |
||
143 | * @return string |
||
144 | */ |
||
145 | public function compileAdd(Blueprint $blueprint, Fluent $command) |
||
155 | |||
156 | /** |
||
157 | * Compile a primary key command. |
||
158 | * |
||
159 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
160 | * @param \Illuminate\Support\Fluent $command |
||
161 | * @return string |
||
162 | */ |
||
163 | public function compilePrimary(Blueprint $blueprint, Fluent $command) |
||
175 | |||
176 | /** |
||
177 | * Compile a foreign key command. |
||
178 | * |
||
179 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
180 | * @param \Illuminate\Support\Fluent $command |
||
181 | * @return string|void |
||
182 | */ |
||
183 | public function compileForeign(Blueprint $blueprint, Fluent $command) |
||
213 | |||
214 | /** |
||
215 | * Compile a unique key command. |
||
216 | * |
||
217 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
218 | * @param \Illuminate\Support\Fluent $command |
||
219 | * @return string |
||
220 | */ |
||
221 | public function compileUnique(Blueprint $blueprint, Fluent $command) |
||
225 | |||
226 | /** |
||
227 | * Compile a plain index key command. |
||
228 | * |
||
229 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
230 | * @param \Illuminate\Support\Fluent $command |
||
231 | * @return string |
||
232 | */ |
||
233 | public function compileIndex(Blueprint $blueprint, Fluent $command) |
||
237 | |||
238 | /** |
||
239 | * Compile a drop table command. |
||
240 | * |
||
241 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
242 | * @param \Illuminate\Support\Fluent $command |
||
243 | * @return string |
||
244 | */ |
||
245 | public function compileDrop(Blueprint $blueprint, Fluent $command) |
||
249 | |||
250 | /** |
||
251 | * Compile a drop table (if exists) command. |
||
252 | * |
||
253 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
254 | * @param \Illuminate\Support\Fluent $command |
||
255 | * @return string |
||
256 | */ |
||
257 | public function compileDropIfExists(Blueprint $blueprint, Fluent $command) |
||
269 | |||
270 | /** |
||
271 | * Compile a drop column command. |
||
272 | * |
||
273 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
274 | * @param \Illuminate\Support\Fluent $command |
||
275 | * @return string |
||
276 | */ |
||
277 | public function compileDropColumn(Blueprint $blueprint, Fluent $command) |
||
285 | |||
286 | /** |
||
287 | * Compile a drop primary key command. |
||
288 | * |
||
289 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
290 | * @param \Illuminate\Support\Fluent $command |
||
291 | * @return string |
||
292 | */ |
||
293 | public function compileDropPrimary(Blueprint $blueprint, Fluent $command) |
||
297 | |||
298 | /** |
||
299 | * @param Blueprint $blueprint |
||
300 | * @param Fluent $command |
||
301 | * @param string $type |
||
302 | * @return string |
||
303 | */ |
||
304 | private function dropConstraint(Blueprint $blueprint, Fluent $command, $type) |
||
315 | |||
316 | /** |
||
317 | * Compile a drop unique key command. |
||
318 | * |
||
319 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
320 | * @param \Illuminate\Support\Fluent $command |
||
321 | * @return string |
||
322 | */ |
||
323 | public function compileDropUnique(Blueprint $blueprint, Fluent $command) |
||
327 | |||
328 | /** |
||
329 | * Compile a drop index command. |
||
330 | * |
||
331 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
332 | * @param \Illuminate\Support\Fluent $command |
||
333 | * @return string |
||
334 | */ |
||
335 | public function compileDropIndex(Blueprint $blueprint, Fluent $command) |
||
339 | |||
340 | /** |
||
341 | * Compile a drop foreign key command. |
||
342 | * |
||
343 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
344 | * @param \Illuminate\Support\Fluent $command |
||
345 | * @return string |
||
346 | */ |
||
347 | public function compileDropForeign(Blueprint $blueprint, Fluent $command) |
||
351 | |||
352 | /** |
||
353 | * Compile a rename table command. |
||
354 | * |
||
355 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
356 | * @param \Illuminate\Support\Fluent $command |
||
357 | * @return string |
||
358 | */ |
||
359 | public function compileRename(Blueprint $blueprint, Fluent $command) |
||
365 | |||
366 | /** |
||
367 | * Compile a rename column command. |
||
368 | * |
||
369 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
370 | * @param \Illuminate\Support\Fluent $command |
||
371 | * @param \Illuminate\Database\Connection $connection |
||
372 | * @return array |
||
373 | */ |
||
374 | public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Connection $connection) |
||
383 | |||
384 | /** |
||
385 | * Create the column definition for a char type. |
||
386 | * |
||
387 | * @param \Illuminate\Support\Fluent $column |
||
388 | * @return string |
||
389 | */ |
||
390 | protected function typeChar(Fluent $column) |
||
394 | |||
395 | /** |
||
396 | * Create the column definition for a string type. |
||
397 | * |
||
398 | * @param \Illuminate\Support\Fluent $column |
||
399 | * @return string |
||
400 | */ |
||
401 | protected function typeString(Fluent $column) |
||
405 | |||
406 | /** |
||
407 | * Create the column definition for a text type. |
||
408 | * |
||
409 | * @param \Illuminate\Support\Fluent $column |
||
410 | * @return string |
||
411 | */ |
||
412 | protected function typeText(Fluent $column) |
||
416 | |||
417 | /** |
||
418 | * Create the column definition for a medium text type. |
||
419 | * |
||
420 | * @param \Illuminate\Support\Fluent $column |
||
421 | * @return string |
||
422 | */ |
||
423 | protected function typeMediumText(Fluent $column) |
||
427 | |||
428 | /** |
||
429 | * Create the column definition for a long text type. |
||
430 | * |
||
431 | * @param \Illuminate\Support\Fluent $column |
||
432 | * @return string |
||
433 | */ |
||
434 | protected function typeLongText(Fluent $column) |
||
438 | |||
439 | /** |
||
440 | * Create the column definition for a integer type. |
||
441 | * |
||
442 | * @param \Illuminate\Support\Fluent $column |
||
443 | * @return string |
||
444 | */ |
||
445 | protected function typeInteger(Fluent $column) |
||
451 | |||
452 | /** |
||
453 | * Create the column definition for a integer type. |
||
454 | * |
||
455 | * @param \Illuminate\Support\Fluent $column |
||
456 | * @return string |
||
457 | */ |
||
458 | protected function typeBigInteger(Fluent $column) |
||
464 | |||
465 | /** |
||
466 | * Create the column definition for a medium integer type. |
||
467 | * |
||
468 | * @param \Illuminate\Support\Fluent $column |
||
469 | * @return string |
||
470 | */ |
||
471 | protected function typeMediumInteger(Fluent $column) |
||
477 | |||
478 | /** |
||
479 | * Create the column definition for a small integer type. |
||
480 | * |
||
481 | * @param \Illuminate\Support\Fluent $column |
||
482 | * @return string |
||
483 | */ |
||
484 | protected function typeSmallInteger(Fluent $column) |
||
490 | |||
491 | /** |
||
492 | * Create the column definition for a tiny integer type. |
||
493 | * |
||
494 | * @param \Illuminate\Support\Fluent $column |
||
495 | * @return string |
||
496 | */ |
||
497 | protected function typeTinyInteger(Fluent $column) |
||
503 | |||
504 | /** |
||
505 | * Create the column definition for a float type. |
||
506 | * |
||
507 | * @param \Illuminate\Support\Fluent $column |
||
508 | * @return string |
||
509 | */ |
||
510 | protected function typeFloat(Fluent $column) |
||
514 | |||
515 | /** |
||
516 | * Create the column definition for a double type. |
||
517 | * |
||
518 | * @param \Illuminate\Support\Fluent $column |
||
519 | * @return string |
||
520 | */ |
||
521 | protected function typeDouble(Fluent $column) |
||
525 | |||
526 | /** |
||
527 | * Create the column definition for a decimal type. |
||
528 | * |
||
529 | * @param \Illuminate\Support\Fluent $column |
||
530 | * @return string |
||
531 | */ |
||
532 | protected function typeDecimal(Fluent $column) |
||
536 | |||
537 | /** |
||
538 | * Create the column definition for a boolean type. |
||
539 | * |
||
540 | * @param \Illuminate\Support\Fluent $column |
||
541 | * @return string |
||
542 | */ |
||
543 | protected function typeBoolean(Fluent $column) |
||
547 | |||
548 | /** |
||
549 | * Create the column definition for a enum type. |
||
550 | * |
||
551 | * @param \Illuminate\Support\Fluent $column |
||
552 | * @return string |
||
553 | */ |
||
554 | protected function typeEnum(Fluent $column) |
||
560 | |||
561 | /** |
||
562 | * Create the column definition for a date type. |
||
563 | * |
||
564 | * @param \Illuminate\Support\Fluent $column |
||
565 | * @return string |
||
566 | */ |
||
567 | protected function typeDate(Fluent $column) |
||
571 | |||
572 | /** |
||
573 | * Create the column definition for a date-time type. |
||
574 | * |
||
575 | * @param \Illuminate\Support\Fluent $column |
||
576 | * @return string |
||
577 | */ |
||
578 | protected function typeDateTime(Fluent $column) |
||
582 | |||
583 | /** |
||
584 | * Create the column definition for a time type. |
||
585 | * |
||
586 | * @param \Illuminate\Support\Fluent $column |
||
587 | * @return string |
||
588 | */ |
||
589 | protected function typeTime(Fluent $column) |
||
593 | |||
594 | /** |
||
595 | * Create the column definition for a timestamp type. |
||
596 | * |
||
597 | * @param \Illuminate\Support\Fluent $column |
||
598 | * @return string |
||
599 | */ |
||
600 | protected function typeTimestamp(Fluent $column) |
||
604 | |||
605 | /** |
||
606 | * Create the column definition for a timestamp type with timezone. |
||
607 | * |
||
608 | * @param Fluent $column |
||
609 | * @return string |
||
610 | */ |
||
611 | protected function typeTimestampTz(Fluent $column) |
||
615 | |||
616 | /** |
||
617 | * Create the column definition for a binary type. |
||
618 | * |
||
619 | * @param \Illuminate\Support\Fluent $column |
||
620 | * @return string |
||
621 | */ |
||
622 | protected function typeBinary(Fluent $column) |
||
626 | |||
627 | /** |
||
628 | * Get the SQL for a nullable column modifier. |
||
629 | * |
||
630 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
631 | * @param \Illuminate\Support\Fluent $column |
||
632 | * @return string |
||
633 | */ |
||
634 | protected function modifyNullable(Blueprint $blueprint, Fluent $column) |
||
651 | |||
652 | /** |
||
653 | * Get the SQL for a default column modifier. |
||
654 | * |
||
655 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
656 | * @param \Illuminate\Support\Fluent $column |
||
657 | * @return string |
||
658 | */ |
||
659 | protected function modifyDefault(Blueprint $blueprint, Fluent $column) |
||
664 | |||
665 | /** |
||
666 | * Get the SQL for an auto-increment column modifier. |
||
667 | * |
||
668 | * @param \Illuminate\Database\Schema\Blueprint $blueprint |
||
669 | * @param \Illuminate\Support\Fluent $column |
||
670 | * @return string|null |
||
671 | */ |
||
672 | protected function modifyIncrement(Blueprint $blueprint, Fluent $column) |
||
678 | |||
679 | /** |
||
680 | * Wrap a single string in keyword identifiers. |
||
681 | * |
||
682 | * @param string $value |
||
683 | * @return string |
||
684 | */ |
||
685 | View Code Duplication | protected function wrapValue($value) |
|
693 | } |
||
694 |
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.