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:
1 | <?php |
||
24 | class TableStyle |
||
25 | { |
||
26 | /** |
||
27 | * @var TableStyle |
||
28 | */ |
||
29 | private static $borderless; |
||
30 | |||
31 | /** |
||
32 | * @var TableStyle |
||
33 | */ |
||
34 | private static $asciiBorder; |
||
35 | |||
36 | /** |
||
37 | * @var TableStyle |
||
38 | */ |
||
39 | private static $solidBorder; |
||
40 | |||
41 | /** |
||
42 | * @var string |
||
43 | */ |
||
44 | private $paddingChar = ' '; |
||
45 | |||
46 | /** |
||
47 | * @var string |
||
48 | */ |
||
49 | private $headerCellFormat = '%s'; |
||
50 | |||
51 | /** |
||
52 | * @var string |
||
53 | */ |
||
54 | private $cellFormat = '%s'; |
||
55 | |||
56 | /** |
||
57 | * @var string |
||
58 | */ |
||
59 | private $columnAlignments = array(); |
||
60 | |||
61 | /** |
||
62 | * @var string |
||
63 | */ |
||
64 | private $defaultColumnAlignment = Alignment::LEFT; |
||
65 | |||
66 | /** |
||
67 | * @var BorderStyle |
||
68 | */ |
||
69 | private $borderStyle; |
||
70 | |||
71 | /** |
||
72 | * @var Style |
||
73 | */ |
||
74 | private $headerCellStyle; |
||
75 | |||
76 | /** |
||
77 | * @var Style |
||
78 | */ |
||
79 | private $cellStyle; |
||
80 | |||
81 | /** |
||
82 | * A borderless style. |
||
83 | * |
||
84 | * @return TableStyle The style. |
||
85 | */ |
||
86 | 1 | public static function borderless() |
|
87 | { |
||
88 | 1 | if (!self::$borderless) { |
|
89 | 1 | self::$borderless = new static(); |
|
90 | 1 | self::$borderless->borderStyle = BorderStyle::none(); |
|
91 | 1 | self::$borderless->borderStyle->setLineHCChar('='); |
|
92 | 1 | self::$borderless->borderStyle->setLineVCChar(' '); |
|
93 | 1 | self::$borderless->borderStyle->setCrossingCChar(' '); |
|
94 | } |
||
95 | |||
96 | 1 | return clone self::$borderless; |
|
97 | } |
||
98 | |||
99 | /** |
||
100 | * A style that uses ASCII characters for drawing borders. |
||
101 | * |
||
102 | * @return TableStyle The style. |
||
103 | */ |
||
104 | 16 | View Code Duplication | public static function asciiBorder() |
|
|||
105 | { |
||
106 | 16 | if (!self::$asciiBorder) { |
|
107 | 1 | self::$asciiBorder = new static(); |
|
108 | 1 | self::$asciiBorder->headerCellFormat = ' %s '; |
|
109 | 1 | self::$asciiBorder->cellFormat = ' %s '; |
|
110 | 1 | self::$asciiBorder->borderStyle = BorderStyle::ascii(); |
|
111 | } |
||
112 | |||
113 | 16 | return clone self::$asciiBorder; |
|
114 | } |
||
115 | |||
116 | /** |
||
117 | * A style that uses Unicode characters for drawing solid borders. |
||
118 | * |
||
119 | * @return TableStyle The style. |
||
120 | */ |
||
121 | 1 | View Code Duplication | public static function solidBorder() |
122 | { |
||
123 | 1 | if (!self::$solidBorder) { |
|
124 | 1 | self::$solidBorder = new static(); |
|
125 | 1 | self::$solidBorder->headerCellFormat = ' %s '; |
|
126 | 1 | self::$solidBorder->cellFormat = ' %s '; |
|
127 | 1 | self::$solidBorder->borderStyle = BorderStyle::solid(); |
|
128 | } |
||
129 | |||
130 | 1 | return clone self::$solidBorder; |
|
131 | } |
||
132 | |||
133 | /** |
||
134 | * Returns the character used to pad cells to the desired width. |
||
135 | * |
||
136 | * @return string The padding character. |
||
137 | */ |
||
138 | 11 | public function getPaddingChar() |
|
142 | |||
143 | /** |
||
144 | * Sets the character used to pad cells to the desired width. |
||
145 | * |
||
146 | * @param string $char The padding character. |
||
147 | * |
||
148 | * @return static The current instance. |
||
149 | */ |
||
150 | public function setPaddingChar($char) |
||
151 | { |
||
152 | $this->paddingChar = $char; |
||
153 | |||
154 | return $this; |
||
155 | } |
||
156 | |||
157 | /** |
||
158 | * Returns the format string for rendering the header cells. |
||
159 | * |
||
160 | * @return string The format string. The string contains the substring "%s" |
||
161 | * where the cell content is inserted. |
||
162 | */ |
||
163 | 11 | public function getHeaderCellFormat() |
|
167 | |||
168 | /** |
||
169 | * Sets the format string for rendering the header cells. |
||
170 | * |
||
171 | * @param string $format The format string. The string should contain the |
||
172 | * substring "%s" where the cell content is inserted. |
||
173 | * |
||
174 | * @return static The current instance. |
||
175 | */ |
||
176 | public function setHeaderCellFormat($format) |
||
177 | { |
||
178 | $this->headerCellFormat = $format; |
||
179 | |||
180 | return $this; |
||
181 | } |
||
182 | |||
183 | /** |
||
184 | * Returns the format string for rendering cells. |
||
185 | * |
||
186 | * @return string The format string. The string contains the substring "%s" |
||
187 | * where the cell content is inserted. |
||
188 | */ |
||
189 | 11 | public function getCellFormat() |
|
193 | |||
194 | /** |
||
195 | * Sets the format string for rendering cells. |
||
196 | * |
||
197 | * @param string $format The format string. The string should contain the |
||
198 | * substring "%s" where the cell content is inserted. |
||
199 | * |
||
200 | * @return static The current instance. |
||
201 | */ |
||
202 | public function setCellFormat($format) |
||
203 | { |
||
204 | $this->cellFormat = $format; |
||
205 | |||
206 | return $this; |
||
207 | } |
||
208 | |||
209 | /** |
||
210 | * Returns the alignments of the table columns. |
||
211 | * |
||
212 | * @param int $nbColumns The number of alignments to return. |
||
213 | * |
||
214 | * @return int[] An array of {@link Alignment} constants indexed by the |
||
215 | * 0-based column keys. |
||
216 | */ |
||
217 | 11 | public function getColumnAlignments($nbColumns) |
|
218 | { |
||
219 | 11 | return array_slice(array_replace( |
|
220 | 11 | array_fill(0, $nbColumns, $this->defaultColumnAlignment), |
|
221 | 11 | $this->columnAlignments |
|
222 | 11 | ), 0, $nbColumns); |
|
223 | } |
||
224 | |||
225 | /** |
||
226 | * Returns the alignment of a given column. |
||
227 | * |
||
228 | * @param int $column The 0-based column key. |
||
229 | * |
||
230 | * @return int The {@link Alignment} constant. |
||
231 | */ |
||
232 | public function getColumnAlignment($column) |
||
233 | { |
||
234 | return isset($this->columnAlignments[$column]) |
||
235 | ? $this->columnAlignments[$column] |
||
236 | : $this->defaultColumnAlignment; |
||
237 | } |
||
238 | |||
239 | /** |
||
240 | * Sets the alignments of the table columns. |
||
241 | * |
||
242 | * @param int[] $alignments An array of {@link Alignment} constants indexed |
||
243 | * by the 0-based column keys. |
||
244 | * |
||
245 | * @return static The current instance. |
||
246 | */ |
||
247 | public function setColumnAlignments(array $alignments) |
||
248 | { |
||
249 | $this->columnAlignments = array(); |
||
250 | |||
251 | foreach ($alignments as $column => $alignment) { |
||
252 | $this->setColumnAlignment($column, $alignment); |
||
253 | } |
||
254 | |||
255 | return $this; |
||
256 | } |
||
257 | |||
258 | /** |
||
259 | * Sets the alignment of a given column. |
||
260 | * |
||
261 | * @param int $column The 0-based column key. |
||
262 | * @param int $alignment The alignment. |
||
263 | * |
||
264 | * @return static The current instance. |
||
265 | */ |
||
266 | 1 | public function setColumnAlignment($column, $alignment) |
|
267 | { |
||
268 | 1 | Assert::oneOf($alignment, Alignment::all(), 'The column alignment must be one of the Alignment constants. Got: %s'); |
|
269 | |||
270 | 1 | $this->columnAlignments[$column] = $alignment; |
|
271 | |||
272 | 1 | return $this; |
|
273 | } |
||
274 | |||
275 | /** |
||
276 | * Returns the default column alignment. |
||
277 | * |
||
278 | * @return int One of the {@link Alignment} constants. |
||
279 | */ |
||
280 | public function getDefaultColumnAlignment() |
||
284 | |||
285 | /** |
||
286 | * Returns the default column alignment. |
||
287 | * |
||
288 | * @param int $alignment One of the {@link Alignment} constants. |
||
289 | * |
||
290 | * @return static The current instance. |
||
291 | */ |
||
292 | public function setDefaultColumnAlignment($alignment) |
||
293 | { |
||
294 | Assert::oneOf($alignment, Alignment::all(), 'The default column alignment must be one of the Alignment constants. Got: %s'); |
||
295 | |||
296 | $this->defaultColumnAlignment = $alignment; |
||
297 | |||
298 | return $this; |
||
299 | } |
||
300 | |||
301 | /** |
||
302 | * Returns the border style. |
||
303 | * |
||
304 | * @return BorderStyle The border style. |
||
305 | */ |
||
306 | 11 | public function getBorderStyle() |
|
310 | |||
311 | /** |
||
312 | * Sets the border style. |
||
313 | * |
||
314 | * @param BorderStyle $borderStyle The border style. |
||
315 | * |
||
316 | * @return static The current instance. |
||
317 | */ |
||
318 | public function setBorderStyle(BorderStyle $borderStyle) |
||
319 | { |
||
320 | $this->borderStyle = $borderStyle; |
||
321 | |||
322 | return $this; |
||
323 | } |
||
324 | |||
325 | /** |
||
326 | * Returns the style of the header cells. |
||
327 | * |
||
328 | * @return Style The header cell style. |
||
329 | */ |
||
330 | 11 | public function getHeaderCellStyle() |
|
334 | |||
335 | /** |
||
336 | * Sets the style of the header cells. |
||
337 | * |
||
338 | * @param Style $style The header cell style. |
||
339 | * |
||
340 | * @return static The current instance. |
||
341 | */ |
||
342 | public function setHeaderCellStyle(Style $style = null) |
||
343 | { |
||
344 | $this->headerCellStyle = $style; |
||
345 | |||
346 | return $this; |
||
347 | } |
||
348 | |||
349 | /** |
||
350 | * Returns the style of the table cells. |
||
351 | * |
||
352 | * @return Style The cell style. |
||
353 | */ |
||
354 | 11 | public function getCellStyle() |
|
358 | |||
359 | /** |
||
360 | * Sets the style of the table cells. |
||
361 | * |
||
362 | * @param Style $style The cell style. |
||
363 | * |
||
364 | * @return static The current instance. |
||
365 | */ |
||
366 | public function setCellStyle(Style $style) |
||
367 | { |
||
368 | $this->cellStyle = $style; |
||
369 | |||
370 | return $this; |
||
371 | } |
||
372 | } |
||
373 |
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.