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 Transaction 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 Transaction, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
7 | class Transaction implements HydratableInterface |
||
8 | { |
||
9 | use PaymentNatureServiceTrait; |
||
10 | use PaymentInfosTrait; |
||
11 | use CustomerInfoTrait; |
||
12 | use ReconciliationIdentifiersTrait; |
||
13 | use CreditCardExpiryTrait; |
||
14 | |||
15 | /** |
||
16 | * @var int |
||
17 | */ |
||
18 | private $transactionId; |
||
19 | |||
20 | /** |
||
21 | * @var string |
||
22 | */ |
||
23 | private $paymentId; |
||
24 | |||
25 | /** |
||
26 | * @var string |
||
27 | */ |
||
28 | private $authType; |
||
29 | |||
30 | /** |
||
31 | * @var string |
||
32 | */ |
||
33 | private $cardStatus; |
||
34 | |||
35 | /** |
||
36 | * @var string |
||
37 | */ |
||
38 | private $creditCardToken; |
||
39 | |||
40 | /** |
||
41 | * @var string |
||
42 | */ |
||
43 | private $creditCardMaskedPan; |
||
44 | |||
45 | /** |
||
46 | * @var string |
||
47 | */ |
||
48 | private $threeDSecureResult; |
||
49 | |||
50 | /** |
||
51 | * @var string |
||
52 | */ |
||
53 | private $liableForChargeback; |
||
54 | |||
55 | /** |
||
56 | * @var string |
||
57 | */ |
||
58 | private $CVVCheckResult; |
||
59 | |||
60 | /** |
||
61 | * @var string |
||
62 | */ |
||
63 | private $blacklistToken; |
||
64 | |||
65 | /** |
||
66 | * @var string |
||
67 | */ |
||
68 | private $shopOrderId; |
||
69 | |||
70 | /** |
||
71 | * @var string |
||
72 | */ |
||
73 | private $shop; |
||
74 | |||
75 | /** |
||
76 | * @var string |
||
77 | */ |
||
78 | private $terminal; |
||
79 | |||
80 | /** |
||
81 | * @var string |
||
82 | */ |
||
83 | private $transactionStatus; |
||
84 | |||
85 | /** |
||
86 | * @var string |
||
87 | */ |
||
88 | private $reasonCode; |
||
89 | |||
90 | /** |
||
91 | * @var int |
||
92 | */ |
||
93 | private $merchantCurrency; |
||
94 | |||
95 | /** |
||
96 | * @var string |
||
97 | */ |
||
98 | private $merchantCurrencyAlpha; |
||
99 | |||
100 | /** |
||
101 | * @var int |
||
102 | */ |
||
103 | private $cardHolderCurrency; |
||
104 | |||
105 | /** |
||
106 | * @var string |
||
107 | */ |
||
108 | private $cardHolderCurrencyAlpha; |
||
109 | |||
110 | /** |
||
111 | * @var float |
||
112 | */ |
||
113 | private $reservedAmount; |
||
114 | |||
115 | /** |
||
116 | * @var float |
||
117 | */ |
||
118 | private $capturedAmount; |
||
119 | |||
120 | /** |
||
121 | * @var float |
||
122 | */ |
||
123 | private $refundedAmount; |
||
124 | |||
125 | /** |
||
126 | * @var float |
||
127 | */ |
||
128 | private $creditedAmount; |
||
129 | |||
130 | /** |
||
131 | * @var float |
||
132 | */ |
||
133 | private $recurringDefaultAmount; |
||
134 | |||
135 | /** |
||
136 | * @var float |
||
137 | */ |
||
138 | private $surchargeAmount; |
||
139 | |||
140 | /** |
||
141 | * @var \DateTimeImmutable |
||
142 | */ |
||
143 | private $createdDate; |
||
144 | |||
145 | /** |
||
146 | * @var \DateTimeImmutable |
||
147 | */ |
||
148 | private $updatedDate; |
||
149 | |||
150 | /** |
||
151 | * @var string |
||
152 | */ |
||
153 | private $paymentNature; |
||
154 | |||
155 | /** |
||
156 | * @var string |
||
157 | */ |
||
158 | private $paymentSchemeName; |
||
159 | |||
160 | /** |
||
161 | * @var string |
||
162 | */ |
||
163 | private $addressVerification; |
||
164 | |||
165 | /** |
||
166 | * @var string |
||
167 | */ |
||
168 | private $addressVerificationDescription; |
||
169 | |||
170 | /** |
||
171 | * @var float |
||
172 | */ |
||
173 | private $fraudRiskScore; |
||
174 | |||
175 | /** |
||
176 | * @var string |
||
177 | */ |
||
178 | private $fraudExplanation; |
||
179 | |||
180 | 9 | public function hydrateXml(\SimpleXMLElement $xml) |
|
233 | |||
234 | /** |
||
235 | * @return int |
||
236 | */ |
||
237 | 3 | public function getTransactionId() : int |
|
241 | |||
242 | /** |
||
243 | * @return string |
||
244 | */ |
||
245 | 3 | public function getPaymentId() : string |
|
249 | |||
250 | /** |
||
251 | * @return string |
||
252 | */ |
||
253 | public function getAuthType(): string |
||
257 | |||
258 | /** |
||
259 | * @return string |
||
260 | */ |
||
261 | 3 | public function getCardStatus() : string |
|
265 | |||
266 | /** |
||
267 | * @return string |
||
268 | */ |
||
269 | 3 | public function getCreditCardToken() : string |
|
273 | |||
274 | /** |
||
275 | * @return string |
||
276 | */ |
||
277 | 3 | public function getCreditCardMaskedPan() : string |
|
281 | |||
282 | /** |
||
283 | * @return string |
||
284 | */ |
||
285 | 3 | public function getThreeDSecureResult() : string |
|
289 | |||
290 | /** |
||
291 | * @return string |
||
292 | */ |
||
293 | 3 | public function getLiableForChargeback() : string |
|
297 | |||
298 | /** |
||
299 | * @return string |
||
300 | */ |
||
301 | public function getCVVCheckResult(): string |
||
305 | |||
306 | /** |
||
307 | * @return string |
||
308 | */ |
||
309 | 3 | public function getBlacklistToken() : string |
|
313 | |||
314 | /** |
||
315 | * @return string |
||
316 | */ |
||
317 | 3 | public function getShopOrderId() : string |
|
321 | |||
322 | /** |
||
323 | * @return string |
||
324 | */ |
||
325 | 3 | public function getShop() : string |
|
329 | |||
330 | /** |
||
331 | * @return string |
||
332 | */ |
||
333 | 3 | public function getTerminal() : string |
|
337 | |||
338 | /** |
||
339 | * @return string |
||
340 | */ |
||
341 | 3 | public function getTransactionStatus() : string |
|
345 | |||
346 | /** |
||
347 | * @return string |
||
348 | */ |
||
349 | 3 | public function getReasonCode() : string |
|
353 | |||
354 | /** |
||
355 | * @return int |
||
356 | */ |
||
357 | 3 | public function getMerchantCurrency() : int |
|
361 | |||
362 | /** |
||
363 | * @return string |
||
364 | */ |
||
365 | 3 | public function getMerchantCurrencyAlpha() : string |
|
369 | |||
370 | /** |
||
371 | * @return int |
||
372 | */ |
||
373 | 3 | public function getCardHolderCurrency() : int |
|
377 | |||
378 | /** |
||
379 | * @return string |
||
380 | */ |
||
381 | 3 | public function getCardHolderCurrencyAlpha() : string |
|
385 | |||
386 | /** |
||
387 | * @return float |
||
388 | */ |
||
389 | 3 | public function getReservedAmount() : float |
|
393 | |||
394 | /** |
||
395 | * @return float |
||
396 | */ |
||
397 | 3 | public function getCapturedAmount() : float |
|
401 | |||
402 | /** |
||
403 | * @return float |
||
404 | */ |
||
405 | 3 | public function getRefundedAmount() : float |
|
409 | |||
410 | /** |
||
411 | * @return float |
||
412 | */ |
||
413 | public function getCreditedAmount(): float |
||
417 | |||
418 | /** |
||
419 | * @return float |
||
420 | */ |
||
421 | 3 | public function getRecurringDefaultAmount() : float |
|
425 | |||
426 | /** |
||
427 | * @return float |
||
428 | */ |
||
429 | public function getSurchargeAmount(): float |
||
433 | |||
434 | /** |
||
435 | * @return \DateTimeImmutable |
||
436 | */ |
||
437 | 3 | public function getCreatedDate() : \DateTimeImmutable |
|
441 | |||
442 | /** |
||
443 | * @return \DateTimeImmutable |
||
444 | */ |
||
445 | 3 | public function getUpdatedDate() : \DateTimeImmutable |
|
449 | |||
450 | /** |
||
451 | * @return string |
||
452 | */ |
||
453 | 3 | public function getPaymentNature() : string |
|
457 | |||
458 | /** |
||
459 | * @return float |
||
460 | */ |
||
461 | 3 | public function getFraudRiskScore() : float |
|
465 | |||
466 | /** |
||
467 | * @return string |
||
468 | */ |
||
469 | 3 | public function getFraudExplanation() : string |
|
473 | } |
||
474 |
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.