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:
1 | <?php declare(strict_types=1); |
||
19 | class Builder |
||
20 | { |
||
21 | /** |
||
22 | * Global options that will be applied to every service created by this builder. |
||
23 | * |
||
24 | * @var array |
||
25 | */ |
||
26 | private $globalOptions = []; |
||
27 | |||
28 | /** @var string */ |
||
29 | private $rootNamespace; |
||
30 | |||
31 | /** |
||
32 | * Defaults that will be applied to options if no values are provided by the user. |
||
33 | * |
||
34 | * @var array |
||
35 | */ |
||
36 | private $defaults = ['urlType' => 'publicURL']; |
||
37 | |||
38 | /** |
||
39 | * @param array $globalOptions Options that will be applied to every service created by this builder. |
||
40 | * Eventually they will be merged (and if necessary overridden) by the |
||
41 | 9 | * service-specific options passed in. |
|
42 | * @param string $rootNamespace API classes' root namespace |
||
43 | 9 | */ |
|
44 | 9 | public function __construct(array $globalOptions = [], $rootNamespace = 'OpenStack') |
|
49 | |||
50 | private function getClasses($namespace) |
||
63 | |||
64 | /** |
||
65 | * This method will return an OpenStack service ready fully built and ready for use. There is |
||
66 | * some initial setup that may prohibit users from directly instantiating the service class |
||
67 | * directly - this setup includes the configuration of the HTTP client's base URL, and the |
||
68 | * attachment of an authentication handler. |
||
69 | * |
||
70 | * @param string $namespace The namespace of the service |
||
71 | * @param array $serviceOptions The service-specific options to use |
||
72 | * |
||
73 | * @return \OpenStack\Common\Service\ServiceInterface |
||
74 | * |
||
75 | * @throws \Exception |
||
76 | */ |
||
77 | public function createService(string $namespace, array $serviceOptions = []): ServiceInterface |
||
88 | 2 | ||
89 | private function stockHttpClient(array &$options, string $serviceName) |
||
107 | |||
108 | /** |
||
109 | * @codeCoverageIgnore |
||
110 | */ |
||
111 | private function addDebugMiddleware(array $options, HandlerStack &$stack) |
||
120 | |||
121 | 6 | /** |
|
122 | * @param array $options |
||
123 | 6 | * |
|
124 | 5 | * @codeCoverageIgnore |
|
125 | 5 | */ |
|
126 | 5 | private function stockAuthHandler(array &$options) |
|
134 | |||
135 | private function getStack(callable $authHandler, Token $token = null): HandlerStack |
||
141 | |||
142 | 2 | private function httpClient(string $baseUrl, HandlerStack $stack, string $serviceType = null, string $microVersion = null): ClientInterface |
|
143 | { |
||
144 | 2 | $clientOptions = [ |
|
145 | 2 | 'base_uri' => Utils::normalizeUrl($baseUrl), |
|
146 | 2 | 'handler' => $stack, |
|
147 | ]; |
||
148 | |||
149 | 6 | if ($microVersion && $serviceType) { |
|
150 | $clientOptions['headers']['OpenStack-API-Version'] = sprintf('%s %s', $serviceType, $microVersion); |
||
151 | 6 | } |
|
152 | 6 | ||
153 | 6 | if (isset($this->globalOptions['requestOptions'])) { |
|
154 | 6 | $clientOptions = array_merge($this->globalOptions['requestOptions'], $clientOptions); |
|
155 | } |
||
156 | return new Client($clientOptions); |
||
157 | 9 | } |
|
158 | |||
159 | 9 | private function mergeOptions(array $serviceOptions): array |
|
175 | } |
||
176 |
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.