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); |
||
| 23 | class Service extends AbstractService |
||
| 24 | 1 | { |
|
| 25 | /** |
||
| 26 | 1 | * Create a new network resource. |
|
| 27 | * |
||
| 28 | * @param array $options {@see \OpenStack\Networking\v2\Api::postNetwork} |
||
| 29 | * |
||
| 30 | * @return Network |
||
| 31 | */ |
||
| 32 | public function createNetwork(array $options): Network |
||
| 36 | 1 | ||
| 37 | /** |
||
| 38 | 1 | * Create a new network resources. |
|
| 39 | * |
||
| 40 | * @param array $options {@see \OpenStack\Networking\v2\Api::postNetworks} |
||
| 41 | * |
||
| 42 | * @return array |
||
| 43 | */ |
||
| 44 | public function createNetworks(array $options): array |
||
| 48 | |||
| 49 | /** |
||
| 50 | 1 | * Retrieve a network object without calling the remote API. Any values provided in the array will populate the |
|
| 51 | * empty object, allowing you greater control without the expense of network transactions. To call the remote API |
||
| 52 | 1 | * and have the response populate the object, call {@see Network::retrieve}. |
|
| 53 | * |
||
| 54 | * @param string $id |
||
| 55 | * |
||
| 56 | * @return Network |
||
| 57 | */ |
||
| 58 | public function getNetwork(string $id): Network |
||
| 62 | 1 | ||
| 63 | /** |
||
| 64 | 1 | * List networks. |
|
| 65 | * |
||
| 66 | * @param array $options {@see \OpenStack\Networking\v2\Api::getNetworks} |
||
| 67 | * |
||
| 68 | * @return \Generator |
||
| 69 | */ |
||
| 70 | public function listNetworks(array $options = []): \Generator |
||
| 74 | 1 | ||
| 75 | /** |
||
| 76 | 1 | * Create a new subnet resource. |
|
| 77 | * |
||
| 78 | * @param array $options {@see \OpenStack\Networking\v2\Api::postSubnet} |
||
| 79 | * |
||
| 80 | * @return Subnet |
||
| 81 | */ |
||
| 82 | public function createSubnet(array $options): Subnet |
||
| 86 | 1 | ||
| 87 | /** |
||
| 88 | 1 | * Create a new subnet resources. |
|
| 89 | * |
||
| 90 | * @param array $options {@see \OpenStack\Networking\v2\Api::postSubnets} |
||
| 91 | * |
||
| 92 | * @return []Subnet |
||
| 93 | */ |
||
| 94 | public function createSubnets(array $options): array |
||
| 98 | |||
| 99 | /** |
||
| 100 | 1 | * Retrieve a subnet object without calling the remote API. Any values provided in the array will populate the |
|
| 101 | * empty object, allowing you greater control without the expense of network transactions. To call the remote API |
||
| 102 | 1 | * and have the response populate the object, call {@see Subnet::retrieve}. |
|
| 103 | * |
||
| 104 | * @param string $id |
||
| 105 | * |
||
| 106 | * @return Subnet |
||
| 107 | */ |
||
| 108 | public function getSubnet(string $id): Subnet |
||
| 112 | 1 | ||
| 113 | /** |
||
| 114 | 1 | * List subnets. |
|
| 115 | * |
||
| 116 | * @param array $options {@see \OpenStack\Networking\v2\Api::getSubnets} |
||
| 117 | * |
||
| 118 | * @return \Generator |
||
| 119 | */ |
||
| 120 | public function listSubnets(array $options = []): \Generator |
||
| 124 | 1 | ||
| 125 | /** |
||
| 126 | 1 | * Create a new port resource. |
|
| 127 | * |
||
| 128 | * @param array $options {@see \OpenStack\Networking\v2\Api::postSinglePort} |
||
| 129 | * |
||
| 130 | * @return Port |
||
| 131 | */ |
||
| 132 | public function createPort(array $options): Port |
||
| 136 | 1 | ||
| 137 | /** |
||
| 138 | 1 | * Create new port resources. |
|
| 139 | * |
||
| 140 | * @param array $options {@see \OpenStack\Networking\v2\Api::postMultiplePorts} |
||
| 141 | * |
||
| 142 | * @return []Port |
||
| 143 | */ |
||
| 144 | public function createPorts(array $options): array |
||
| 148 | |||
| 149 | /** |
||
| 150 | 1 | * Retrieve a subnet object without calling the remote API. Any values provided in the array will populate the |
|
| 151 | * empty object, allowing you greater control without the expense of network transactions. To call the remote API |
||
| 152 | 1 | * and have the response populate the object, call {@see Port::retrieve}. |
|
| 153 | * |
||
| 154 | * @param string $id |
||
| 155 | * |
||
| 156 | * @return Port |
||
| 157 | */ |
||
| 158 | public function getPort(string $id): Port |
||
| 162 | 1 | ||
| 163 | /** |
||
| 164 | 1 | * List ports. |
|
| 165 | * |
||
| 166 | * @param array $options {@see \OpenStack\Networking\v2\Api::getPorts} |
||
| 167 | * |
||
| 168 | * @return \Generator |
||
| 169 | */ |
||
| 170 | public function listPorts(array $options = []): \Generator |
||
| 174 | |||
| 175 | /** |
||
| 176 | * Lists quotas for projects with non-default quota values. |
||
| 177 | * |
||
| 178 | * @return \Generator |
||
| 179 | */ |
||
| 180 | public function listQuotas(): \Generator |
||
| 184 | |||
| 185 | /** |
||
| 186 | * Lists quotas for a project. |
||
| 187 | * |
||
| 188 | * Retrieve a quota object without calling the remote API. Any values provided in the array will populate the |
||
| 189 | * empty object, allowing you greater control without the expense of network transactions. To call the remote API |
||
| 190 | * and have the response populate the object, call {@see Quota::retrieve}. |
||
| 191 | * |
||
| 192 | * @param string $tenantId |
||
| 193 | * |
||
| 194 | * @return Quota |
||
| 195 | */ |
||
| 196 | public function getQuota(string $tenantId): Quota |
||
| 200 | |||
| 201 | /** |
||
| 202 | * Lists default quotas for a project |
||
| 203 | * |
||
| 204 | * @param string $tenantId |
||
| 205 | * |
||
| 206 | * @return Quota |
||
| 207 | */ |
||
| 208 | View Code Duplication | public function getDefaultQuota(string $tenantId): Quota |
|
| 209 | { |
||
| 210 | $quota = $this->model(Quota::class, ['tenantId' => $tenantId]); |
||
| 211 | $quota->populateFromResponse($this->execute($this->api->getQuotaDefault(), ['tenantId' => $tenantId])); |
||
| 212 | |||
| 213 | return $quota; |
||
| 214 | } |
||
| 215 | |||
| 216 | /** |
||
| 217 | * Lists loadbalancers for projects |
||
| 218 | * |
||
| 219 | * @return \Generator |
||
| 220 | */ |
||
| 221 | public function listLoadBalancers(): \Generator |
||
| 225 | |||
| 226 | /** |
||
| 227 | * Retrieve an instance of a LoadBalancer object |
||
| 228 | * |
||
| 229 | * @param string $id |
||
| 230 | * |
||
| 231 | * @return LoadBalancer |
||
| 232 | */ |
||
| 233 | public function getLoadBalancer(string $id): LoadBalancer |
||
| 237 | |||
| 238 | /** |
||
| 239 | * Create a new loadbalancer resource. |
||
| 240 | * |
||
| 241 | * @param array $options {@see \OpenStack\Networking\v2\Api::postLoadBalancer} |
||
| 242 | * |
||
| 243 | * @return LoadBalancer |
||
| 244 | */ |
||
| 245 | public function createLoadBalancer(array $options): LoadBalancer |
||
| 249 | |||
| 250 | /** |
||
| 251 | * Lists loadbalancer listeners |
||
| 252 | * |
||
| 253 | * @return \Generator |
||
| 254 | */ |
||
| 255 | public function listLoadBalancerListeners(): \Generator |
||
| 259 | |||
| 260 | /** |
||
| 261 | * Retrieve an instance of a loadbalancer listener object |
||
| 262 | * |
||
| 263 | * @param string $id |
||
| 264 | * |
||
| 265 | * @return LoadBalancerListener |
||
| 266 | */ |
||
| 267 | public function getLoadBalancerListener(string $id): LoadBalancerListener |
||
| 271 | |||
| 272 | /** |
||
| 273 | * Create a new loadbalancer Listener resource. |
||
| 274 | * |
||
| 275 | * @param array $options {@see \OpenStack\Networking\v2\Api::postLoadBalancerListener} |
||
| 276 | * |
||
| 277 | * @return LoadBalancerListener |
||
| 278 | */ |
||
| 279 | public function createLoadBalancerListener(array $options): LoadBalancerListener |
||
| 283 | |||
| 284 | /** |
||
| 285 | * Lists loadbalancer pools |
||
| 286 | * |
||
| 287 | * @return \Generator |
||
| 288 | */ |
||
| 289 | public function listLoadBalancerPools(): \Generator |
||
| 293 | |||
| 294 | /** |
||
| 295 | * Retrieve an instance of a loadbalancer Pool object |
||
| 296 | * |
||
| 297 | * @param string $id |
||
| 298 | * |
||
| 299 | * @return LoadBalancerPool |
||
| 300 | */ |
||
| 301 | public function getLoadBalancerPool(string $id): LoadBalancerPool |
||
| 305 | |||
| 306 | /** |
||
| 307 | * Create a new loadbalancer Pool resource. |
||
| 308 | * |
||
| 309 | * @param array $options {@see \OpenStack\Networking\v2\Api::postLoadBalancerPool} |
||
| 310 | * |
||
| 311 | * @return LoadBalancerPool |
||
| 312 | */ |
||
| 313 | public function createLoadBalancerPool(array $options): LoadBalancerPool |
||
| 317 | |||
| 318 | /** |
||
| 319 | * Lists loadbalancer members |
||
| 320 | * |
||
| 321 | * @param string $poolId |
||
| 322 | * @return \Generator |
||
| 323 | */ |
||
| 324 | public function listLoadBalancerMembers(string $poolId): \Generator |
||
| 328 | |||
| 329 | /** |
||
| 330 | * Retrieve an instance of a loadbalancer Member object |
||
| 331 | * |
||
| 332 | * @param string $poolId |
||
| 333 | * @param string $memberId |
||
| 334 | * |
||
| 335 | * @return LoadBalancerMember |
||
| 336 | */ |
||
| 337 | public function getLoadBalancerMember(string $poolId, string $memberId): LoadBalancerMember |
||
| 341 | |||
| 342 | /** |
||
| 343 | * Create a new loadbalancer member resource. |
||
| 344 | * |
||
| 345 | * @param array $options {@see \OpenStack\Networking\v2\Api::postLoadBalancerMember} |
||
| 346 | * |
||
| 347 | * @return LoadBalancerMember |
||
| 348 | */ |
||
| 349 | public function createLoadBalancerMember(array $options): LoadBalancerMember |
||
| 353 | |||
| 354 | /** |
||
| 355 | * Lists loadbalancer healthmonitors |
||
| 356 | * |
||
| 357 | * @return \Generator |
||
| 358 | */ |
||
| 359 | public function listLoadBalancerHealthMonitors(): \Generator |
||
| 363 | |||
| 364 | /** |
||
| 365 | * Retrieve an instance of a loadbalancer healthmonitor object |
||
| 366 | * |
||
| 367 | * @param string $id |
||
| 368 | * |
||
| 369 | * @return LoadBalancerHealthMonitor |
||
| 370 | */ |
||
| 371 | public function getLoadBalancerHealthMonitor(string $id): LoadBalancerHealthMonitor |
||
| 375 | |||
| 376 | /** |
||
| 377 | * Create a new loadbalancer healthmonitor resource. |
||
| 378 | * |
||
| 379 | * @param array $options {@see \OpenStack\Networking\v2\Api::postLoadBalancerHealthMonitor} |
||
| 380 | * |
||
| 381 | * @return LoadBalancerHealthMonitor |
||
| 382 | */ |
||
| 383 | public function createLoadBalancerHealthMonitor(array $options): LoadBalancerHealthMonitor |
||
| 387 | |||
| 388 | /** |
||
| 389 | * Retrieve a network IP availability object without calling the remote API. Any values provided in the array will populate the |
||
| 390 | * empty object, allowing you greater control without the expense of network transactions. To call the remote API |
||
| 391 | * and have the response populate the object, call {@see NetworkIpAvailabilities::retrieve}. |
||
| 392 | * |
||
| 393 | * @param string $id |
||
| 394 | * |
||
| 395 | * @return NetworkIpAvailability |
||
| 396 | */ |
||
| 397 | public function getNetworkIpAvailability(string $id): NetworkIpAvailability |
||
| 401 | |||
| 402 | /** |
||
| 403 | * List network IP availability(es) |
||
| 404 | * |
||
| 405 | * @param array $options {@see \OpenStack\Networking\v2\Api::getNetworkIpAvailabilities() |
||
| 406 | * |
||
| 407 | * @return \Generator |
||
| 408 | */ |
||
| 409 | public function listNetworkIpAvailabilities(array $options = []): \Generator |
||
| 413 | } |
||
| 414 |
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the interface: