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 TableBuilder 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 TableBuilder, and based on these observations, apply Extract Interface, too.
1 | <?php namespace Anomaly\Streams\Platform\Ui\Table; |
||
26 | class TableBuilder |
||
27 | { |
||
28 | use DispatchesJobs; |
||
29 | use FiresCallbacks; |
||
30 | |||
31 | /** |
||
32 | * The ajax flag. |
||
33 | * |
||
34 | * @var bool |
||
35 | */ |
||
36 | protected $ajax = false; |
||
37 | |||
38 | /** |
||
39 | * The table model. |
||
40 | * |
||
41 | * @var null|string |
||
42 | */ |
||
43 | protected $model = null; |
||
44 | |||
45 | /** |
||
46 | * The entries handler. |
||
47 | * |
||
48 | * @var null|string |
||
49 | */ |
||
50 | protected $entries = null; |
||
51 | |||
52 | /** |
||
53 | * The table repository. |
||
54 | * |
||
55 | * @var null|TableRepositoryInterface |
||
56 | */ |
||
57 | protected $repository = null; |
||
58 | |||
59 | /** |
||
60 | * The views configuration. |
||
61 | * |
||
62 | * @var array|string |
||
63 | */ |
||
64 | protected $views = []; |
||
65 | |||
66 | /** |
||
67 | * The filters configuration. |
||
68 | * |
||
69 | * @var array|string |
||
70 | */ |
||
71 | protected $filters = []; |
||
72 | |||
73 | /** |
||
74 | * The columns configuration. |
||
75 | * |
||
76 | * @var array|string |
||
77 | */ |
||
78 | protected $columns = []; |
||
79 | |||
80 | /** |
||
81 | * The buttons configuration. |
||
82 | * |
||
83 | * @var array|string |
||
84 | */ |
||
85 | protected $buttons = []; |
||
86 | |||
87 | /** |
||
88 | * The actions configuration. |
||
89 | * |
||
90 | * @var array|string |
||
91 | */ |
||
92 | protected $actions = []; |
||
93 | |||
94 | /** |
||
95 | * The table options. |
||
96 | * |
||
97 | * @var array |
||
98 | */ |
||
99 | protected $options = []; |
||
100 | |||
101 | /** |
||
102 | * The table assets. |
||
103 | * |
||
104 | * @var array |
||
105 | */ |
||
106 | protected $assets = []; |
||
107 | |||
108 | /** |
||
109 | * The table object. |
||
110 | * |
||
111 | * @var Table |
||
112 | */ |
||
113 | protected $table; |
||
114 | |||
115 | /** |
||
116 | * Create a new TableBuilder instance. |
||
117 | * |
||
118 | * @param Table $table |
||
119 | */ |
||
120 | public function __construct(Table $table) |
||
121 | { |
||
122 | $this->table = $table; |
||
123 | } |
||
124 | |||
125 | /** |
||
126 | * Build the table. |
||
127 | * |
||
128 | * @return $this |
||
129 | */ |
||
130 | public function build() |
||
131 | { |
||
132 | $this->fire('ready', ['builder' => $this]); |
||
133 | |||
134 | $this->dispatch(new BuildTable($this)); |
||
135 | |||
136 | $this->fire('built', ['builder' => $this]); |
||
137 | |||
138 | return $this; |
||
139 | } |
||
140 | |||
141 | /** |
||
142 | * Make the table response. |
||
143 | * |
||
144 | * @return $this |
||
145 | */ |
||
146 | public function make() |
||
154 | |||
155 | /** |
||
156 | * Return the table response. |
||
157 | * |
||
158 | * @return $this |
||
159 | */ |
||
160 | public function load() |
||
161 | { |
||
162 | $this->dispatch(new LoadTable($this)); |
||
163 | $this->dispatch(new AddAssets($this)); |
||
164 | $this->dispatch(new MakeTable($this)); |
||
165 | |||
166 | return $this; |
||
167 | } |
||
168 | |||
169 | /** |
||
170 | * Trigger post operations |
||
171 | * for the table. |
||
172 | * |
||
173 | * @return $this |
||
174 | */ |
||
175 | public function post() |
||
183 | |||
184 | /** |
||
185 | * Render the table. |
||
186 | * |
||
187 | * @return Response |
||
188 | */ |
||
189 | public function render() |
||
199 | |||
200 | /** |
||
201 | * Get the ajax flag. |
||
202 | * |
||
203 | * @return bool |
||
204 | */ |
||
205 | public function isAjax() |
||
209 | |||
210 | /** |
||
211 | * Set the ajax flag. |
||
212 | * |
||
213 | * @param $ajax |
||
214 | * @return $this |
||
215 | */ |
||
216 | public function setAjax($ajax) |
||
222 | |||
223 | /** |
||
224 | * Get the table object. |
||
225 | * |
||
226 | * @return Table |
||
227 | */ |
||
228 | public function getTable() |
||
232 | |||
233 | /** |
||
234 | * Set the table model. |
||
235 | * |
||
236 | * @param string $model |
||
237 | * @return $this |
||
238 | */ |
||
239 | public function setModel($model) |
||
245 | |||
246 | /** |
||
247 | * Get the table model. |
||
248 | * |
||
249 | * @return null|string |
||
250 | */ |
||
251 | public function getModel() |
||
255 | |||
256 | /** |
||
257 | * Get the entries. |
||
258 | * |
||
259 | * @return null|string |
||
260 | */ |
||
261 | public function getEntries() |
||
265 | |||
266 | /** |
||
267 | * Set the entries. |
||
268 | * |
||
269 | * @param $entries |
||
270 | * @return $this |
||
271 | */ |
||
272 | public function setEntries($entries) |
||
278 | |||
279 | /** |
||
280 | * Get the repository. |
||
281 | * |
||
282 | * @return TableRepositoryInterface|null |
||
283 | */ |
||
284 | public function getRepository() |
||
288 | |||
289 | /** |
||
290 | * Set the repository. |
||
291 | * |
||
292 | * @param TableRepositoryInterface $repository |
||
293 | * @return $this |
||
294 | */ |
||
295 | public function setRepository(TableRepositoryInterface $repository) |
||
301 | |||
302 | /** |
||
303 | * Set the views configuration. |
||
304 | * |
||
305 | * @param $views |
||
306 | * @return $this |
||
307 | */ |
||
308 | public function setViews($views) |
||
314 | |||
315 | /** |
||
316 | * Get the views configuration. |
||
317 | * |
||
318 | * @return array |
||
319 | */ |
||
320 | public function getViews() |
||
324 | |||
325 | /** |
||
326 | * Set the filters configuration. |
||
327 | * |
||
328 | * @param $filters |
||
329 | * @return $this |
||
330 | */ |
||
331 | public function setFilters($filters) |
||
337 | |||
338 | /** |
||
339 | * Get the filters configuration. |
||
340 | * |
||
341 | * @return array |
||
342 | */ |
||
343 | public function getFilters() |
||
347 | |||
348 | /** |
||
349 | * Add a column configuration. |
||
350 | * |
||
351 | * @param $column |
||
352 | * @return $this |
||
353 | */ |
||
354 | public function addColumn($column) |
||
355 | { |
||
356 | $this->columns[] = $column; |
||
357 | |||
358 | return $this; |
||
359 | } |
||
360 | |||
361 | /** |
||
362 | * Set the columns configuration. |
||
363 | * |
||
364 | * @param $columns |
||
365 | * @return $this |
||
366 | */ |
||
367 | public function setColumns($columns) |
||
373 | |||
374 | /** |
||
375 | * Get the columns configuration. |
||
376 | * |
||
377 | * @return array |
||
378 | */ |
||
379 | public function getColumns() |
||
383 | |||
384 | /** |
||
385 | * Set the buttons configuration. |
||
386 | * |
||
387 | * @param $buttons |
||
388 | * @return $this |
||
389 | */ |
||
390 | public function setButtons($buttons) |
||
396 | |||
397 | /** |
||
398 | * Get the buttons configuration. |
||
399 | * |
||
400 | * @return array |
||
401 | */ |
||
402 | public function getButtons() |
||
406 | |||
407 | /** |
||
408 | * Set the actions configuration. |
||
409 | * |
||
410 | * @param $actions |
||
411 | * @return $this |
||
412 | */ |
||
413 | public function setActions($actions) |
||
419 | |||
420 | /** |
||
421 | * Get the actions configuration. |
||
422 | * |
||
423 | * @return array |
||
424 | */ |
||
425 | public function getActions() |
||
429 | |||
430 | /** |
||
431 | * The the options. |
||
432 | * |
||
433 | * @return array |
||
434 | */ |
||
435 | public function getOptions() |
||
439 | |||
440 | /** |
||
441 | * Set the options. |
||
442 | * |
||
443 | * @param array $options |
||
444 | * @return $this |
||
445 | */ |
||
446 | public function setOptions($options) |
||
447 | { |
||
448 | $this->options = $options; |
||
449 | |||
450 | return $this; |
||
451 | } |
||
452 | |||
453 | /** |
||
454 | * Get an option value. |
||
455 | * |
||
456 | * @param $key |
||
457 | * @param null $default |
||
458 | * @return mixed |
||
459 | */ |
||
460 | public function getOption($key, $default = null) |
||
464 | |||
465 | /** |
||
466 | * Set an option value. |
||
467 | * |
||
468 | * @param $key |
||
469 | * @param $value |
||
470 | * @return $this |
||
471 | */ |
||
472 | public function setOption($key, $value) |
||
478 | |||
479 | /** |
||
480 | * Get the assets. |
||
481 | * |
||
482 | * @return array |
||
483 | */ |
||
484 | public function getAssets() |
||
488 | |||
489 | /** |
||
490 | * Set the assets. |
||
491 | * |
||
492 | * @param $assets |
||
493 | * @return $this |
||
494 | */ |
||
495 | public function setAssets($assets) |
||
501 | |||
502 | /** |
||
503 | * Add an asset. |
||
504 | * |
||
505 | * @param $collection |
||
506 | * @param $asset |
||
507 | * @return $this |
||
508 | */ |
||
509 | View Code Duplication | public function addAsset($collection, $asset) |
|
519 | |||
520 | /** |
||
521 | * Get the table's stream. |
||
522 | * |
||
523 | * @return \Anomaly\Streams\Platform\Stream\Contract\StreamInterface|null |
||
524 | */ |
||
525 | public function getTableStream() |
||
529 | |||
530 | /** |
||
531 | * Get the table model. |
||
532 | * |
||
533 | * @return \Anomaly\Streams\Platform\Model\EloquentModel|null |
||
534 | */ |
||
535 | public function getTableModel() |
||
539 | |||
540 | /** |
||
541 | * Get a table option value. |
||
542 | * |
||
543 | * @param $key |
||
544 | * @param null $default |
||
545 | * @return mixed |
||
546 | */ |
||
547 | public function getTableOption($key, $default = null) |
||
551 | |||
552 | /** |
||
553 | * Set a table option value. |
||
554 | * |
||
555 | * @param $key |
||
556 | * @param $value |
||
557 | * @return $this |
||
558 | */ |
||
559 | public function setTableOption($key, $value) |
||
565 | |||
566 | /** |
||
567 | * Get the table options. |
||
568 | * |
||
569 | * @return Collection |
||
570 | */ |
||
571 | public function getTableOptions() |
||
575 | |||
576 | /** |
||
577 | * Set the table entries. |
||
578 | * |
||
579 | * @param Collection $entries |
||
580 | * @return $this |
||
581 | */ |
||
582 | public function setTableEntries(Collection $entries) |
||
588 | |||
589 | /** |
||
590 | * Get the table entries. |
||
591 | * |
||
592 | * @return Collection |
||
593 | */ |
||
594 | public function getTableEntries() |
||
598 | |||
599 | /** |
||
600 | * Get the table actions. |
||
601 | * |
||
602 | * @return Component\Action\ActionCollection |
||
603 | */ |
||
604 | public function getTableActions() |
||
608 | |||
609 | /** |
||
610 | * Get the table filters. |
||
611 | * |
||
612 | * @return Component\Filter\FilterCollection |
||
613 | */ |
||
614 | public function getTableFilters() |
||
618 | |||
619 | /** |
||
620 | * Get the table filter. |
||
621 | * |
||
622 | * @param $key |
||
623 | * @return FilterInterface |
||
624 | */ |
||
625 | public function getTableFilter($key) |
||
629 | |||
630 | /** |
||
631 | * Get a table filter value. |
||
632 | * |
||
633 | * @param $key |
||
634 | * @param null $default |
||
635 | * @return mixed |
||
636 | */ |
||
637 | public function getTableFilterValue($key, $default = null) |
||
645 | |||
646 | /** |
||
647 | * Get the table views. |
||
648 | * |
||
649 | * @return Component\View\ViewCollection |
||
650 | */ |
||
651 | public function getTableViews() |
||
655 | |||
656 | /** |
||
657 | * Set the table views. |
||
658 | * |
||
659 | * @param ViewCollection $views |
||
660 | * @return $this |
||
661 | */ |
||
662 | public function setTableViews(ViewCollection $views) |
||
668 | |||
669 | /** |
||
670 | * Return whether the table has an active view. |
||
671 | * |
||
672 | * @return bool |
||
673 | */ |
||
674 | public function hasActiveView() |
||
678 | |||
679 | /** |
||
680 | * Return whether the table view is active. |
||
681 | * |
||
682 | * @param $slug |
||
683 | * @return bool |
||
684 | */ |
||
685 | public function isActiveView($slug) |
||
693 | |||
694 | /** |
||
695 | * Add a row to the table. |
||
696 | * |
||
697 | * @param RowInterface $row |
||
698 | * @return $this |
||
699 | */ |
||
700 | public function addTableRow(RowInterface $row) |
||
706 | |||
707 | /** |
||
708 | * Add data to the table. |
||
709 | * |
||
710 | * @param $key |
||
711 | * @param $value |
||
712 | * @return $this |
||
713 | */ |
||
714 | public function addTableData($key, $value) |
||
720 | |||
721 | /** |
||
722 | * Set the table response. |
||
723 | * |
||
724 | * @param Response $response |
||
725 | */ |
||
726 | public function setTableResponse(Response $response) |
||
730 | |||
731 | /** |
||
732 | * Get the table response. |
||
733 | * |
||
734 | * @return null|Response |
||
735 | */ |
||
736 | public function getTableResponse() |
||
740 | |||
741 | /** |
||
742 | * Get the table content. |
||
743 | * |
||
744 | * @return null|string |
||
745 | */ |
||
746 | public function getTableContent() |
||
750 | |||
751 | /** |
||
752 | * Get a request value. |
||
753 | * |
||
754 | * @param $key |
||
755 | * @param null $default |
||
756 | * @return mixed |
||
757 | */ |
||
758 | public function getRequestValue($key, $default = null) |
||
762 | } |
||
763 |
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.