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 Attribute 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 Attribute, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
21 | class Attribute extends JsonObject |
||
22 | { |
||
23 | // identifiers for the Api Product Attribute Types: |
||
24 | const T_UNKNOWN = 'unknown'; // zero, should evaluate to false |
||
25 | |||
26 | const PROP_VALUE = "value"; |
||
27 | const PROP_KEY = "key"; |
||
28 | const PROP_NAME = "name"; |
||
29 | const PROP_CURRENCY_CODE = "currencyCode"; |
||
30 | const PROP_CENT_AMOUNT = "centAmount"; |
||
31 | const PROP_TYPE_ID = "typeId"; |
||
32 | const PROP_ID = "id"; |
||
33 | const PROP_LABEL = "label"; |
||
34 | |||
35 | const API_BOOL = 'boolean'; |
||
36 | const API_NUMBER = 'number'; |
||
37 | const API_TEXT = 'text'; |
||
38 | const API_LTEXT = 'ltext'; |
||
39 | const API_LENUM = 'lenum'; |
||
40 | const API_ENUM = 'enum'; |
||
41 | const API_MONEY = 'money'; |
||
42 | const API_DATE = 'date'; |
||
43 | const API_TIME = 'time'; |
||
44 | const API_DATETIME = 'datetime'; |
||
45 | const API_SET = 'set'; |
||
46 | const API_NESTED = 'nested'; |
||
47 | const API_REFERENCE = 'reference'; |
||
48 | |||
49 | protected static $types = []; |
||
50 | |||
51 | 48 | public function fieldDefinitions() |
|
58 | |||
59 | 48 | public function fieldDefinition($field) |
|
77 | |||
78 | /** |
||
79 | * @param $attributeName |
||
80 | * @param $value |
||
81 | * @return mixed |
||
82 | */ |
||
83 | 40 | protected function getApiType($attributeName, $value) |
|
98 | |||
99 | /** |
||
100 | * @param AttributeDefinition $definition |
||
101 | * @return $this |
||
102 | */ |
||
103 | 40 | public function setAttributeDefinition(AttributeDefinition $definition) |
|
109 | |||
110 | /** |
||
111 | * @param string $field |
||
112 | */ |
||
113 | 41 | protected function initialize($field) |
|
122 | |||
123 | 36 | private function setApiType($attributeName, $valueType, $elementType = null) |
|
137 | |||
138 | /** |
||
139 | * @return bool |
||
140 | */ |
||
141 | 1 | public function getValueAsBool() |
|
147 | |||
148 | /** |
||
149 | * @return int|float |
||
150 | */ |
||
151 | 2 | public function getValueAsNumber() |
|
157 | |||
158 | /** |
||
159 | * @return string |
||
160 | */ |
||
161 | 1 | public function getValueAsString() |
|
167 | |||
168 | /** |
||
169 | * @return LocalizedString |
||
170 | */ |
||
171 | 1 | public function getValueAsLocalizedString() |
|
177 | |||
178 | /** |
||
179 | * @return LocalizedEnum |
||
180 | */ |
||
181 | 1 | public function getValueAsLocalizedEnum() |
|
187 | |||
188 | /** |
||
189 | * @return Enum |
||
190 | */ |
||
191 | 1 | public function getValueAsEnum() |
|
197 | |||
198 | /** |
||
199 | * @return Money |
||
200 | */ |
||
201 | 1 | public function getValueAsMoney() |
|
207 | |||
208 | /** |
||
209 | * @return DateDecorator |
||
210 | */ |
||
211 | public function getValueAsDate() |
||
217 | |||
218 | /** |
||
219 | * @return TimeDecorator |
||
220 | */ |
||
221 | public function getValueAsTime() |
||
227 | |||
228 | /** |
||
229 | * @return DateTimeDecorator |
||
230 | */ |
||
231 | public function getValueAsDateTime() |
||
237 | |||
238 | /** |
||
239 | * @return AttributeCollection |
||
240 | */ |
||
241 | 1 | public function getValueAsNested() |
|
247 | |||
248 | /** |
||
249 | * @return Reference |
||
250 | */ |
||
251 | 1 | public function getValueAsReference() |
|
257 | |||
258 | /** |
||
259 | * @return Set |
||
260 | */ |
||
261 | 1 | public function getValueAsBoolSet() |
|
267 | |||
268 | /** |
||
269 | * @return Set |
||
270 | */ |
||
271 | 2 | public function getValueAsNumberSet() |
|
277 | |||
278 | /** |
||
279 | * @return Set |
||
280 | */ |
||
281 | 1 | public function getValueAsStringSet() |
|
287 | |||
288 | /** |
||
289 | * @return Set |
||
290 | */ |
||
291 | 1 | public function getValueAsLocalizedStringSet() |
|
297 | |||
298 | /** |
||
299 | * @return Set |
||
300 | */ |
||
301 | 1 | public function getValueAsLocalizedEnumSet() |
|
307 | |||
308 | /** |
||
309 | * @return Set |
||
310 | */ |
||
311 | 2 | public function getValueAsEnumSet() |
|
317 | |||
318 | /** |
||
319 | * @return Set |
||
320 | */ |
||
321 | 1 | public function getValueAsMoneySet() |
|
327 | |||
328 | /** |
||
329 | * @return Set |
||
330 | */ |
||
331 | public function getValueAsDateSet() |
||
337 | |||
338 | /** |
||
339 | * @return Set |
||
340 | */ |
||
341 | public function getValueAsTimeSet() |
||
347 | |||
348 | /** |
||
349 | * @return Set |
||
350 | */ |
||
351 | public function getValueAsDateTimeSet() |
||
357 | |||
358 | /** |
||
359 | * @return Set |
||
360 | */ |
||
361 | 1 | public function getValueAsNestedSet() |
|
367 | |||
368 | /** |
||
369 | * @return Set |
||
370 | */ |
||
371 | 1 | public function getValueAsReferenceSet() |
|
377 | |||
378 | /** |
||
379 | * @param $value |
||
380 | * @return string |
||
381 | */ |
||
382 | 15 | protected function guessApiType($value) |
|
406 | |||
407 | /** |
||
408 | * @param $value |
||
409 | * @param string[] $keys |
||
410 | * @return bool |
||
411 | */ |
||
412 | 9 | protected function hasKeys($value, $keys) |
|
420 | |||
421 | 15 | protected function guessUnknown($value) |
|
425 | |||
426 | 13 | protected function guessTextLike($value) |
|
430 | |||
431 | 14 | protected function guessBool($value) |
|
435 | |||
436 | 11 | protected function guessNumber($value) |
|
440 | |||
441 | 9 | View Code Duplication | protected function guessEnum($value) |
449 | |||
450 | 8 | View Code Duplication | protected function guessLocalizedEnum($value) |
458 | |||
459 | 7 | View Code Duplication | protected function guessMoney($value) |
467 | |||
468 | 6 | View Code Duplication | protected function guessReference($value) |
476 | |||
477 | 4 | protected function guessLocalizedText($value) |
|
485 | |||
486 | 2 | protected function guessSet($value) |
|
494 | |||
495 | 3 | protected function guessNested($value) |
|
506 | } |
||
507 |
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.