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 HtmlTable 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 HtmlTable, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
20 | class HtmlTable extends HtmlSemDoubleElement { |
||
21 | use TableTrait; |
||
22 | private $_colCount; |
||
23 | private $_compileParts; |
||
24 | private $_footer; |
||
25 | private $_afterCompileEvents; |
||
26 | private $_activeRowSelector; |
||
27 | |||
28 | public function __construct($identifier, $rowCount, $colCount) { |
||
36 | |||
37 | /** |
||
38 | * {@inheritDoc} |
||
39 | * @see TableTrait::getTable() |
||
40 | */ |
||
41 | protected function getTable() { |
||
44 | |||
45 | /** |
||
46 | * Returns/create eventually a part of the table corresponding to the $key : thead, tbody or tfoot |
||
47 | * @param string $key |
||
48 | * @return HtmlTableContent |
||
49 | */ |
||
50 | public function getPart($key) { |
||
59 | |||
60 | /** |
||
61 | * Returns/create eventually the body of the table |
||
62 | * @return HtmlTableContent |
||
63 | */ |
||
64 | public function getBody() { |
||
67 | |||
68 | /** |
||
69 | * Returns the number of rows (TR) |
||
70 | * @return int |
||
71 | */ |
||
72 | public function getRowCount() { |
||
75 | |||
76 | /** |
||
77 | * Returns/create eventually the header of the table |
||
78 | * @return HtmlTableContent |
||
79 | */ |
||
80 | public function getHeader() { |
||
83 | |||
84 | /** |
||
85 | * Returns/create eventually the footer of the table |
||
86 | * @return \Ajax\semantic\html\content\table\HtmlTableContent |
||
87 | */ |
||
88 | public function getFooter() { |
||
91 | |||
92 | /** |
||
93 | * Checks if the part corresponding to $key exists |
||
94 | * @param string $key |
||
95 | * @return boolean |
||
96 | */ |
||
97 | public function hasPart($key) { |
||
100 | |||
101 | /** |
||
102 | * |
||
103 | * @param int $rowCount |
||
104 | * @param int $colCount |
||
105 | * @return HtmlTableContent |
||
106 | */ |
||
107 | public function setRowCount($rowCount, $colCount) { |
||
111 | |||
112 | /** |
||
113 | * Returns the cell (HtmlTD) at position $row,$col |
||
114 | * @param int $row |
||
115 | * @param int $col |
||
116 | * @return HtmlTD |
||
117 | */ |
||
118 | public function getCell($row, $col) { |
||
121 | |||
122 | /** |
||
123 | * Retuns the row at $rowIndex |
||
124 | * @param int $rowIndex |
||
125 | * @return HtmlTR |
||
126 | */ |
||
127 | public function getRow($rowIndex) { |
||
130 | |||
131 | /** |
||
132 | * Adds a new row and sets $values to his cols |
||
133 | * @param array $values |
||
134 | * @return HtmlTR |
||
135 | */ |
||
136 | public function addRow($values=array()) { |
||
141 | |||
142 | /** |
||
143 | * adds and returns a new row |
||
144 | * @return HtmlTR |
||
145 | */ |
||
146 | public function newRow() { |
||
149 | |||
150 | /** |
||
151 | * Sets the tbody values |
||
152 | * @param array $values values in an array of array |
||
153 | * @return HtmlTable |
||
154 | */ |
||
155 | public function setValues($values=array()) { |
||
159 | |||
160 | /** |
||
161 | * Sets the header values |
||
162 | * @param array $values |
||
163 | * @return HtmlTableContent |
||
164 | */ |
||
165 | public function setHeaderValues($values=array()) { |
||
168 | |||
169 | /** |
||
170 | * Sets the footer values |
||
171 | * @param array $values |
||
172 | * @return HtmlTableContent |
||
173 | */ |
||
174 | public function setFooterValues($values=array()) { |
||
177 | |||
178 | /** |
||
179 | * Sets values to the col at index $colIndex |
||
180 | * @param int $colIndex |
||
181 | * @param array $values |
||
182 | * @return HtmlTable |
||
183 | */ |
||
184 | public function setColValues($colIndex, $values=array()) { |
||
188 | |||
189 | /** |
||
190 | * Sets values to the row at index $rowIndex |
||
191 | * @param int $rowIndex |
||
192 | * @param array $values |
||
193 | * @return HtmlTable |
||
194 | */ |
||
195 | public function setRowValues($rowIndex, $values=array()) { |
||
199 | |||
200 | public function addColVariations($colIndex, $variations=array()) { |
||
203 | |||
204 | /** |
||
205 | * Sets the col alignment to center |
||
206 | * @param int $colIndex |
||
207 | * @return HtmlTable |
||
208 | */ |
||
209 | public function colCenter($colIndex) { |
||
212 | |||
213 | /** |
||
214 | * Sets the col alignment to right |
||
215 | * @param int $colIndex |
||
216 | * @return HtmlTable |
||
217 | */ |
||
218 | public function colRight($colIndex) { |
||
221 | |||
222 | /** |
||
223 | * Sets col alignment to left |
||
224 | * @param int $colIndex |
||
225 | * @return HtmlTable |
||
226 | */ |
||
227 | public function colLeft($colIndex) { |
||
230 | |||
231 | private function colAlign($colIndex, $function) { |
||
244 | |||
245 | /** |
||
246 | * Applies a format on each cell when $callback returns true |
||
247 | * @param callable $callback function with the cell as parameter, must return a boolean |
||
248 | * @param string $format css class to apply |
||
249 | * @return HtmlTable |
||
250 | */ |
||
251 | public function conditionalCellFormat($callback, $format) { |
||
255 | |||
256 | /** |
||
257 | * Applies a format on each row when $callback returns true |
||
258 | * @param callable $callback function with the row as parameter, must return a boolean |
||
259 | * @param string $format css class to apply |
||
260 | * @return HtmlTable |
||
261 | */ |
||
262 | public function conditionalRowFormat($callback, $format) { |
||
266 | |||
267 | /** |
||
268 | * Applies a callback function on each cell |
||
269 | * @param callable $callback |
||
270 | * @return HtmlTable |
||
271 | */ |
||
272 | public function applyCells($callback) { |
||
276 | |||
277 | /** |
||
278 | * Applies a callback function on each row |
||
279 | * @param callable $callback |
||
280 | * @return HtmlTable |
||
281 | */ |
||
282 | public function applyRows($callback) { |
||
286 | |||
287 | /** |
||
288 | * |
||
289 | * {@inheritDoc} |
||
290 | * |
||
291 | * @see HtmlSemDoubleElement::compile() |
||
292 | */ |
||
293 | public function compile(JsUtils $js=NULL, &$view=NULL) { |
||
301 | |||
302 | protected function compile_once(JsUtils $js=NULL, &$view=NULL) { |
||
310 | |||
311 | /** |
||
312 | * |
||
313 | * {@inheritDoc} |
||
314 | * |
||
315 | * @see BaseHtml::fromDatabaseObject() |
||
316 | */ |
||
317 | public function fromDatabaseObject($object, $function) { |
||
330 | |||
331 | /** |
||
332 | * Sets the parts of the Table to compile |
||
333 | * @param array $parts array of thead,tbody,tfoot |
||
334 | * @return HtmlTable |
||
335 | */ |
||
336 | public function setCompileParts($parts=["tbody"]) { |
||
340 | |||
341 | public function refresh(){ |
||
345 | |||
346 | public function run(JsUtils $js){ |
||
352 | |||
353 | /** |
||
354 | * The callback function called after the insertion of each row when fromDatabaseObjects is called |
||
355 | * callback function takes the parameters $row : the row inserted and $object: the instance of model used |
||
356 | * @param callable $callback |
||
357 | * @return HtmlTable |
||
358 | */ |
||
359 | public function onNewRow($callback) { |
||
363 | |||
364 | /** |
||
365 | * Defines how a row is selectable |
||
366 | * @param string $class |
||
367 | * @param string $event |
||
368 | * @param boolean $multiple |
||
369 | * @return HtmlTable |
||
370 | */ |
||
371 | public function setActiveRowSelector($class="active",$event="click",$multiple=false){ |
||
375 | |||
376 | View Code Duplication | public function hideColumn($colIndex){ |
|
386 | |||
387 | View Code Duplication | public function setColWidth($colIndex,$width){ |
|
396 | } |
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.