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 PublicAPIClient 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 PublicAPIClient, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
16 | class PublicAPIClient |
||
17 | { |
||
18 | /** |
||
19 | * @var CredentialsInterface |
||
20 | */ |
||
21 | private $credentials; |
||
22 | |||
23 | /** |
||
24 | * @var TransportInterface |
||
25 | */ |
||
26 | private $transport; |
||
27 | |||
28 | /** |
||
29 | * @var LoggerInterface |
||
30 | */ |
||
31 | private $logger; |
||
32 | |||
33 | /** |
||
34 | * @var ValidatorV1 |
||
35 | */ |
||
36 | private $validator; |
||
37 | |||
38 | /** |
||
39 | * Client constructor. |
||
40 | * @param CredentialsInterface $credentials |
||
41 | * @param TransportInterface $transport |
||
42 | * @param LoggerInterface|null $logger |
||
43 | */ |
||
44 | public function __construct( |
||
54 | |||
55 | /** |
||
56 | * Sends PSR-7 compatible request to Covery and returns |
||
57 | * |
||
58 | * @param RequestInterface $request |
||
59 | * @return string |
||
60 | * @throws IoException |
||
61 | */ |
||
62 | public function send(RequestInterface $request) |
||
84 | |||
85 | /** |
||
86 | * Utility method, that prepares and signs request |
||
87 | * |
||
88 | * @param RequestInterface $request |
||
89 | * @return RequestInterface |
||
90 | */ |
||
91 | private function prepareRequest(RequestInterface $request) |
||
103 | |||
104 | /** |
||
105 | * Utility function, that handles error response from Covery |
||
106 | * |
||
107 | * @param ResponseInterface $response |
||
108 | * @throws Exception |
||
109 | */ |
||
110 | private function handleNot200(ResponseInterface $response) |
||
139 | |||
140 | /** |
||
141 | * Utility method, that reads JSON data |
||
142 | * |
||
143 | * @param $string |
||
144 | * @return mixed|null |
||
145 | * @throws Exception |
||
146 | */ |
||
147 | private function readJson($string) |
||
168 | |||
169 | /** |
||
170 | * Sends request to Covery and returns access level, associated with |
||
171 | * used credentials |
||
172 | * |
||
173 | * This method can be used for Covery health check and availability |
||
174 | * On any problem (network, credentials, server side) this method |
||
175 | * will throw an exception |
||
176 | * |
||
177 | * @return string |
||
178 | * @throws Exception |
||
179 | */ |
||
180 | public function ping() |
||
189 | |||
190 | /** |
||
191 | * Sends envelope to Covery and returns it's ID on Covery side |
||
192 | * Before sending, validation is performed |
||
193 | * |
||
194 | * @param EnvelopeInterface $envelope |
||
195 | * @return int |
||
196 | * @throws Exception |
||
197 | */ |
||
198 | View Code Duplication | public function sendEvent(EnvelopeInterface $envelope) |
|
212 | |||
213 | /** |
||
214 | * Sends postback envelope to Covery and returns it's ID on Covery side |
||
215 | * Before sending, validation is performed |
||
216 | * |
||
217 | * @param EnvelopeInterface $envelope |
||
218 | * @return int |
||
219 | * @throws Exception |
||
220 | */ |
||
221 | View Code Duplication | public function sendPostback(EnvelopeInterface $envelope) |
|
235 | |||
236 | /** |
||
237 | * Sends envelope to Covery for analysis |
||
238 | * |
||
239 | * @param EnvelopeInterface $envelope |
||
240 | * @return Result |
||
241 | * @throws Exception |
||
242 | */ |
||
243 | public function makeDecision(EnvelopeInterface $envelope) |
||
276 | |||
277 | /** |
||
278 | * Sends kycProof envelope to Covery and returns KycProofResult on Covery side |
||
279 | * |
||
280 | * @param EnvelopeInterface $envelope |
||
281 | * @return KycProofResult |
||
282 | * @throws EnvelopeValidationException |
||
283 | * @throws Exception |
||
284 | * @throws IoException |
||
285 | */ |
||
286 | public function sendKycProof(EnvelopeInterface $envelope) |
||
316 | } |
||
317 |
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.