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 PaymentsApiClient 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 PaymentsApiClient, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
46 | class PaymentsApiClient extends CommonApiClient implements PaymentsApiClientInterface |
||
47 | { |
||
48 | const SUB_URL_CREATE_PAYMENT = 'api/payment'; |
||
49 | const SUB_URL_CREATE_PAYMENT_SUBMIT = 'api/payment/submit'; |
||
50 | const SUB_URL_RETRIEVE_PAYMENT = 'api/payment/%s'; |
||
51 | const SUB_URL_LIST_PAYMENTS = 'api/payment'; |
||
52 | const SUB_URL_REFUND_PAYMENT = 'api/payment/refund/%s'; |
||
53 | const SUB_URL_AUTHORIZE_PAYMENT = 'api/payment/authorize/%s'; |
||
54 | const SUB_URL_REMIND_PAYMENT = 'api/payment/remind/%s'; |
||
55 | const SUB_URL_COLLECT_PAYMENTS = 'api/payment/collect/%s'; |
||
56 | const SUB_URL_LATE_PAYMENTS = 'api/payment/late-payment/%s'; |
||
57 | const SUB_URL_SHIPPING_GOODS_PAYMENT = 'api/payment/shipping-goods/%s'; |
||
58 | const SUB_URL_CANCEL_PAYMENT = 'api/payment/cancel/%s'; |
||
59 | const SUB_URL_RETRIEVE_API_CALL = 'api/%s'; |
||
60 | const SUB_URL_LIST_PAYMENT_OPTIONS = 'api/shop/%s/payment-options/%s'; |
||
61 | const SUB_URL_LIST_PAYMENT_OPTIONS_VARIANTS = 'api/shop/%s/payment-options/variants/%s'; |
||
62 | const SUB_URL_TRANSACTION = 'api/rest/v1/transactions/%s'; |
||
63 | |||
64 | /** |
||
65 | * {@inheritdoc} |
||
66 | * |
||
67 | * @throws \Exception |
||
68 | */ |
||
69 | View Code Duplication | public function createPaymentRequest(CreatePaymentRequest $createPaymentRequest) |
|
89 | |||
90 | /** |
||
91 | * {@inheritdoc} |
||
92 | * |
||
93 | * @throws \Exception |
||
94 | */ |
||
95 | View Code Duplication | public function submitPaymentRequest(SubmitPaymentRequest $submitPaymentRequest) |
|
116 | |||
117 | /** |
||
118 | * {@inheritdoc} |
||
119 | * |
||
120 | * @throws \Exception |
||
121 | */ |
||
122 | public function retrievePaymentRequest($paymentId) |
||
135 | |||
136 | /** |
||
137 | * {@inheritdoc} |
||
138 | * |
||
139 | * @throws \Exception |
||
140 | */ |
||
141 | public function listPaymentsRequest(ListPaymentsRequest $listPaymentsRequest) |
||
155 | |||
156 | /** |
||
157 | * {@inheritdoc} |
||
158 | * |
||
159 | * @throws \Exception |
||
160 | */ |
||
161 | public function refundPaymentRequest($paymentId, $amount) |
||
178 | |||
179 | /** |
||
180 | * {@inheritdoc} |
||
181 | * |
||
182 | * @throws \Exception |
||
183 | */ |
||
184 | View Code Duplication | public function authorizePaymentRequest($paymentId, AuthorizePaymentRequest $paymentRequest = null) |
|
198 | |||
199 | /** |
||
200 | * {@inheritdoc} |
||
201 | * |
||
202 | * @throws \Exception |
||
203 | * |
||
204 | * @deprecated This request is only available for Santander DE Invoice and not used anywhere |
||
205 | */ |
||
206 | public function remindPaymentRequest($paymentId) |
||
219 | |||
220 | /** |
||
221 | * {@inheritdoc} |
||
222 | * |
||
223 | * @throws \Exception |
||
224 | * |
||
225 | * @deprecated This request is only available for Santander DE Invoice and not used anywhere |
||
226 | */ |
||
227 | public function collectPaymentsRequest($paymentId) |
||
240 | |||
241 | /** |
||
242 | * {@inheritdoc} |
||
243 | * |
||
244 | * @throws \Exception |
||
245 | * |
||
246 | * @deprecated This request is only available for Santander DE Invoice and not used anywhere |
||
247 | */ |
||
248 | public function latePaymentsRequest($paymentId) |
||
261 | |||
262 | /** |
||
263 | * {@inheritdoc} |
||
264 | * |
||
265 | * @throws \Exception |
||
266 | */ |
||
267 | View Code Duplication | public function shippingGoodsPaymentRequest( |
|
283 | |||
284 | /** |
||
285 | * {@inheritdoc} |
||
286 | * |
||
287 | * @throws \Exception |
||
288 | */ |
||
289 | public function cancelPaymentRequest($paymentId) |
||
302 | |||
303 | /** |
||
304 | * {@inheritdoc} |
||
305 | * |
||
306 | * @throws \Exception |
||
307 | */ |
||
308 | public function retrieveApiCallRequest($callId) |
||
321 | |||
322 | /** |
||
323 | * {@inheritdoc} |
||
324 | * |
||
325 | * @throws \Exception |
||
326 | */ |
||
327 | View Code Duplication | public function listPaymentOptionsRequest($params = [], $businessUuid = '', $channel = '') |
|
338 | |||
339 | /** |
||
340 | * {@inheritdoc} |
||
341 | * |
||
342 | * @throws \Exception |
||
343 | */ |
||
344 | View Code Duplication | public function listPaymentOptionsWithVariantsRequest($params = [], $businessUuid = '', $channel = '') |
|
355 | |||
356 | /** |
||
357 | * {@inheritdoc} |
||
358 | * |
||
359 | * @throws \Exception |
||
360 | */ |
||
361 | public function getTransactionRequest($paymentId) |
||
374 | |||
375 | /** |
||
376 | * Returns URL for Create Payment path |
||
377 | * |
||
378 | * @return string |
||
379 | */ |
||
380 | protected function getCreatePaymentURL() |
||
384 | |||
385 | /** |
||
386 | * Returns URL for Submit Payment path |
||
387 | * |
||
388 | * @return string |
||
389 | */ |
||
390 | protected function getSubmitPaymentURL() |
||
394 | |||
395 | /** |
||
396 | * Returns URL for Retrieve Payment path |
||
397 | * |
||
398 | * @param string $paymentId |
||
399 | * |
||
400 | * @return string |
||
401 | */ |
||
402 | protected function getRetrievePaymentURL($paymentId) |
||
406 | |||
407 | /** |
||
408 | * Returns URL for List Payments path |
||
409 | * |
||
410 | * @return string |
||
411 | */ |
||
412 | protected function getListPaymentsURL() |
||
416 | |||
417 | /** |
||
418 | * Returns URL for Refund Payment path |
||
419 | * |
||
420 | * @param string $paymentId |
||
421 | * |
||
422 | * @return string |
||
423 | */ |
||
424 | protected function getRefundPaymentURL($paymentId) |
||
428 | |||
429 | /** |
||
430 | * Returns URL for Authorize Payment path |
||
431 | * |
||
432 | * @param string $paymentId |
||
433 | * |
||
434 | * @return string |
||
435 | */ |
||
436 | protected function getAuthorizePaymentURL($paymentId) |
||
440 | |||
441 | /** |
||
442 | * Returns URL for Remind Payment path |
||
443 | * |
||
444 | * @param string $paymentId |
||
445 | * |
||
446 | * @return string |
||
447 | */ |
||
448 | protected function getRemindPaymentURL($paymentId) |
||
452 | |||
453 | /** |
||
454 | * Returns URL for Collect Payment path |
||
455 | * |
||
456 | * @param string $paymentId |
||
457 | * |
||
458 | * @return string |
||
459 | */ |
||
460 | protected function getCollectPaymentsURL($paymentId) |
||
464 | |||
465 | /** |
||
466 | * Returns URL for Late Payments path |
||
467 | * |
||
468 | * @param string $paymentId |
||
469 | * |
||
470 | * @return string |
||
471 | */ |
||
472 | protected function getLatePaymentsURL($paymentId) |
||
476 | |||
477 | /** |
||
478 | * Returns URL for Shipping Goods Payment path |
||
479 | * |
||
480 | * @param string $paymentId |
||
481 | * |
||
482 | * @return string |
||
483 | */ |
||
484 | protected function getShippingGoodsPaymentURL($paymentId) |
||
488 | |||
489 | /** |
||
490 | * Returns URL for Cancel Payment path |
||
491 | * |
||
492 | * @param string $paymentId |
||
493 | * |
||
494 | * @return string |
||
495 | */ |
||
496 | protected function getCancelPaymentURL($paymentId) |
||
500 | |||
501 | /** |
||
502 | * Returns URL for Retrieve API Call path |
||
503 | * |
||
504 | * @param string $callId |
||
505 | * |
||
506 | * @return string |
||
507 | */ |
||
508 | protected function getRetrieveApiCallURL($callId) |
||
512 | |||
513 | /** |
||
514 | * Returns URL for Available Payment Options path |
||
515 | * |
||
516 | * @param string $businessUuid |
||
517 | * @param string $channel |
||
518 | * @param array $params |
||
519 | * |
||
520 | * @return string |
||
521 | */ |
||
522 | protected function getListPaymentOptionsURL($businessUuid, $channel, $params = []) |
||
528 | |||
529 | /** |
||
530 | * Returns URL for Available Payment Options request |
||
531 | * |
||
532 | * @param string $businessUuid |
||
533 | * @param string $channel |
||
534 | * @param array $params |
||
535 | * |
||
536 | * @return string |
||
537 | */ |
||
538 | protected function getListPaymentOptionsVariantsURL($businessUuid, $channel, $params = []) |
||
544 | |||
545 | /** |
||
546 | * Returns URL to Transaction path |
||
547 | * |
||
548 | * @param int $paymentId |
||
549 | * |
||
550 | * @return string |
||
551 | */ |
||
552 | protected function getTransactionURL($paymentId) |
||
556 | } |
||
557 |
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.