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 Client 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 Client, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
24 | class Client extends AbstractHasDispatcher implements ClientInterface |
||
25 | { |
||
26 | /** @deprecated Use [request.options][params] */ |
||
27 | const REQUEST_PARAMS = 'request.params'; |
||
28 | |||
29 | const REQUEST_OPTIONS = 'request.options'; |
||
30 | const CURL_OPTIONS = 'curl.options'; |
||
31 | const SSL_CERT_AUTHORITY = 'ssl.certificate_authority'; |
||
32 | const DISABLE_REDIRECTS = RedirectPlugin::DISABLE; |
||
33 | const DEFAULT_SELECT_TIMEOUT = 1.0; |
||
34 | const MAX_HANDLES = 3; |
||
35 | |||
36 | /** @var Collection Default HTTP headers to set on each request */ |
||
37 | protected $defaultHeaders; |
||
38 | |||
39 | /** @var string The user agent string to set on each request */ |
||
40 | protected $userAgent; |
||
41 | |||
42 | /** @var Collection Parameter object holding configuration data */ |
||
43 | private $config; |
||
44 | |||
45 | /** @var Url Base URL of the client */ |
||
46 | private $baseUrl; |
||
47 | |||
48 | /** @var CurlMultiInterface CurlMulti object used internally */ |
||
49 | private $curlMulti; |
||
50 | |||
51 | /** @var UriTemplateInterface URI template owned by the client */ |
||
52 | private $uriTemplate; |
||
53 | |||
54 | /** @var RequestFactoryInterface Request factory used by the client */ |
||
55 | protected $requestFactory; |
||
56 | |||
57 | public static function getAllEvents() |
||
61 | |||
62 | /** |
||
63 | * @param string $baseUrl Base URL of the web service |
||
64 | * @param array|Collection $config Configuration settings |
||
65 | * |
||
66 | * @throws RuntimeException if cURL is not installed |
||
67 | */ |
||
68 | public function __construct($baseUrl = '', $config = null) |
||
85 | |||
86 | View Code Duplication | final public function setConfig($config) |
|
98 | |||
99 | final public function getConfig($key = false) |
||
103 | |||
104 | /** |
||
105 | * Set a default request option on the client that will be used as a default for each request |
||
106 | * |
||
107 | * @param string $keyOrPath request.options key (e.g. allow_redirects) or path to a nested key (e.g. headers/foo) |
||
108 | * @param mixed $value Value to set |
||
109 | * |
||
110 | * @return $this |
||
111 | */ |
||
112 | public function setDefaultOption($keyOrPath, $value) |
||
119 | |||
120 | /** |
||
121 | * Retrieve a default request option from the client |
||
122 | * |
||
123 | * @param string $keyOrPath request.options key (e.g. allow_redirects) or path to a nested key (e.g. headers/foo) |
||
124 | * |
||
125 | * @return mixed|null |
||
126 | */ |
||
127 | public function getDefaultOption($keyOrPath) |
||
133 | |||
134 | final public function setSslVerification($certificateAuthority = true, $verifyPeer = true, $verifyHost = 2) |
||
171 | |||
172 | public function createRequest($method = 'GET', $uri = null, $headers = null, $body = null, array $options = array()) |
||
203 | |||
204 | public function getBaseUrl($expand = true) |
||
208 | |||
209 | public function setBaseUrl($url) |
||
215 | |||
216 | public function setUserAgent($userAgent, $includeDefault = false) |
||
225 | |||
226 | /** |
||
227 | * Get the default User-Agent string to use with Guzzle |
||
228 | * |
||
229 | * @return string |
||
230 | */ |
||
231 | public function getDefaultUserAgent() |
||
237 | |||
238 | public function get($uri = null, $headers = null, $options = array()) |
||
245 | |||
246 | public function head($uri = null, $headers = null, array $options = array()) |
||
250 | |||
251 | public function delete($uri = null, $headers = null, $body = null, array $options = array()) |
||
255 | |||
256 | public function put($uri = null, $headers = null, $body = null, array $options = array()) |
||
260 | |||
261 | public function patch($uri = null, $headers = null, $body = null, array $options = array()) |
||
265 | |||
266 | public function post($uri = null, $headers = null, $postBody = null, array $options = array()) |
||
270 | |||
271 | public function options($uri = null, array $options = array()) |
||
275 | |||
276 | public function send($requests) |
||
290 | |||
291 | /** |
||
292 | * Set a curl multi object to be used internally by the client for transferring requests. |
||
293 | * |
||
294 | * @param CurlMultiInterface $curlMulti Multi object |
||
295 | * |
||
296 | * @return self |
||
297 | */ |
||
298 | public function setCurlMulti(CurlMultiInterface $curlMulti) |
||
304 | |||
305 | /** |
||
306 | * @return CurlMultiInterface|CurlMultiProxy |
||
307 | */ |
||
308 | public function getCurlMulti() |
||
319 | |||
320 | public function setRequestFactory(RequestFactoryInterface $factory) |
||
326 | |||
327 | /** |
||
328 | * Set the URI template expander to use with the client |
||
329 | * |
||
330 | * @param UriTemplateInterface $uriTemplate URI template expander |
||
331 | * |
||
332 | * @return self |
||
333 | */ |
||
334 | public function setUriTemplate(UriTemplateInterface $uriTemplate) |
||
340 | |||
341 | /** |
||
342 | * Expand a URI template while merging client config settings into the template variables |
||
343 | * |
||
344 | * @param string $template Template to expand |
||
345 | * @param array $variables Variables to inject |
||
346 | * |
||
347 | * @return string |
||
348 | */ |
||
349 | protected function expandTemplate($template, array $variables = null) |
||
358 | |||
359 | /** |
||
360 | * Get the URI template expander used by the client |
||
361 | * |
||
362 | * @return UriTemplateInterface |
||
363 | */ |
||
364 | protected function getUriTemplate() |
||
372 | |||
373 | /** |
||
374 | * Send multiple requests in parallel |
||
375 | * |
||
376 | * @param array $requests Array of RequestInterface objects |
||
377 | * |
||
378 | * @return array Returns an array of Response objects |
||
379 | */ |
||
380 | protected function sendMultiple(array $requests) |
||
396 | |||
397 | /** |
||
398 | * Prepare a request to be sent from the Client by adding client specific behaviors and properties to the request. |
||
399 | * |
||
400 | * @param RequestInterface $request Request to prepare for the client |
||
401 | * @param array $options Options to apply to the request |
||
402 | * |
||
403 | * @return RequestInterface |
||
404 | */ |
||
405 | protected function prepareRequest(RequestInterface $request, array $options = array()) |
||
434 | |||
435 | /** |
||
436 | * Initializes SSL settings |
||
437 | */ |
||
438 | protected function initSsl() |
||
456 | |||
457 | /** |
||
458 | * @deprecated |
||
459 | */ |
||
460 | public function getDefaultHeaders() |
||
465 | |||
466 | /** |
||
467 | * @deprecated |
||
468 | */ |
||
469 | View Code Duplication | public function setDefaultHeaders($headers) |
|
482 | |||
483 | /** |
||
484 | * @deprecated |
||
485 | */ |
||
486 | public function preparePharCacert($md5Check = true) |
||
490 | |||
491 | /** |
||
492 | * Copies the phar cacert from a phar into the temp directory. |
||
493 | * |
||
494 | * @param string $pharCacertPath Path to the phar cacert. For example: |
||
495 | * 'phar://aws.phar/Guzzle/Http/Resources/cacert.pem' |
||
496 | * |
||
497 | * @return string Returns the path to the extracted cacert file. |
||
498 | * @throws \RuntimeException Throws if the phar cacert cannot be found or |
||
499 | * the file cannot be copied to the temp dir. |
||
500 | */ |
||
501 | public static function extractPharCacert($pharCacertPath) |
||
524 | } |
||
525 |
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.