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 Index 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 Index, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 41 | class Index implements SearchableInterface |
||
| 42 | { |
||
| 43 | /** |
||
| 44 | * Index name. |
||
| 45 | * |
||
| 46 | * @var string Index name |
||
| 47 | */ |
||
| 48 | protected $_name; |
||
| 49 | |||
| 50 | /** |
||
| 51 | * Client object. |
||
| 52 | * |
||
| 53 | * @var Client Client object |
||
| 54 | */ |
||
| 55 | protected $_client; |
||
| 56 | |||
| 57 | /** |
||
| 58 | * Creates a new index object. |
||
| 59 | * |
||
| 60 | * All the communication to and from an index goes of this object |
||
| 61 | * |
||
| 62 | * @param Client $client Client object |
||
| 63 | * @param string $name Index name |
||
| 64 | */ |
||
| 65 | public function __construct(Client $client, string $name) |
||
| 70 | |||
| 71 | /** |
||
| 72 | * Return Index Stats. |
||
| 73 | * |
||
| 74 | * @return \Elastica\Index\Stats |
||
| 75 | */ |
||
| 76 | public function getStats() |
||
| 80 | |||
| 81 | /** |
||
| 82 | * Return Index Recovery. |
||
| 83 | * |
||
| 84 | * @return \Elastica\Index\Recovery |
||
| 85 | */ |
||
| 86 | public function getRecovery() |
||
| 90 | |||
| 91 | /** |
||
| 92 | * Sets the mappings for the current index. |
||
| 93 | * |
||
| 94 | * @param Mapping $mapping MappingType object |
||
| 95 | * @param array $query querystring when put mapping (for example update_all_types) |
||
| 96 | * |
||
| 97 | * @return Response |
||
| 98 | */ |
||
| 99 | public function setMapping(Mapping $mapping, array $query = []): Response |
||
| 103 | |||
| 104 | /** |
||
| 105 | * Gets all mappings for the current index. |
||
| 106 | * |
||
| 107 | * @return array |
||
| 108 | */ |
||
| 109 | public function getMapping(): array |
||
| 119 | |||
| 120 | /** |
||
| 121 | * Returns the index settings object. |
||
| 122 | * |
||
| 123 | * @return \Elastica\Index\Settings Settings object |
||
| 124 | */ |
||
| 125 | public function getSettings() |
||
| 129 | |||
| 130 | /** |
||
| 131 | * @param string $id |
||
| 132 | * @param array|string $data |
||
| 133 | * |
||
| 134 | * @return Document |
||
| 135 | */ |
||
| 136 | public function createDocument(string $id = '', $data = []) |
||
| 140 | |||
| 141 | /** |
||
| 142 | * Uses _bulk to send documents to the server. |
||
| 143 | * |
||
| 144 | * @param Document[] $docs Array of Elastica\Document |
||
| 145 | * @param array $options Array of query params to use for query. For possible options check es api |
||
| 146 | * |
||
| 147 | * @return ResponseSet |
||
| 148 | * |
||
| 149 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html |
||
| 150 | */ |
||
| 151 | public function updateDocuments(array $docs, array $options = []) |
||
| 159 | |||
| 160 | /** |
||
| 161 | * Update entries in the db based on a query. |
||
| 162 | * |
||
| 163 | * @param Query|string|array $query Query object or array |
||
| 164 | * @param AbstractScript $script Script |
||
| 165 | * @param array $options Optional params |
||
| 166 | * |
||
| 167 | * @return Response |
||
| 168 | * |
||
| 169 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update-by-query.html |
||
| 170 | */ |
||
| 171 | public function updateByQuery($query, AbstractScript $script, array $options = []) |
||
| 185 | |||
| 186 | /** |
||
| 187 | * Adds the given document to the search index. |
||
| 188 | * |
||
| 189 | * @param Document $doc Document with data |
||
| 190 | * |
||
| 191 | * @return Response |
||
| 192 | */ |
||
| 193 | public function addDocument(Document $doc) |
||
| 237 | |||
| 238 | /** |
||
| 239 | * Uses _bulk to send documents to the server. |
||
| 240 | * |
||
| 241 | * @param array|Document[] $docs Array of Elastica\Document |
||
| 242 | * @param array $options Array of query params to use for query. For possible options check es api |
||
| 243 | * |
||
| 244 | * @return ResponseSet |
||
| 245 | * |
||
| 246 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html |
||
| 247 | */ |
||
| 248 | public function addDocuments(array $docs, array $options = []) |
||
| 256 | |||
| 257 | /** |
||
| 258 | * Get the document from search index. |
||
| 259 | * |
||
| 260 | * @param int|string $id Document id |
||
| 261 | * @param array $options options for the get request |
||
| 262 | * |
||
| 263 | * @throws \Elastica\Exception\ResponseException |
||
| 264 | * @throws NotFoundException |
||
| 265 | * |
||
| 266 | * @return Document |
||
| 267 | */ |
||
| 268 | public function getDocument($id, array $options = []): Document |
||
| 294 | |||
| 295 | /** |
||
| 296 | * Deletes a document by its unique identifier. |
||
| 297 | * |
||
| 298 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete.html |
||
| 299 | * |
||
| 300 | * @param string $id Document id |
||
| 301 | * @param array $options |
||
| 302 | * |
||
| 303 | * @throws NotFoundException |
||
| 304 | * |
||
| 305 | * @return Response Response object |
||
| 306 | */ |
||
| 307 | public function deleteById(string $id, array $options = []): Response |
||
| 327 | |||
| 328 | /** |
||
| 329 | * Deletes entries in the db based on a query. |
||
| 330 | * |
||
| 331 | * @param Query|AbstractQuery|string|array $query Query object or array |
||
| 332 | * @param array $options Optional params |
||
| 333 | * |
||
| 334 | * @return Response |
||
| 335 | * |
||
| 336 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/5.0/docs-delete-by-query.html |
||
| 337 | */ |
||
| 338 | public function deleteByQuery($query, array $options = []) |
||
| 348 | |||
| 349 | /** |
||
| 350 | * Deletes the index. |
||
| 351 | * |
||
| 352 | * @return Response Response object |
||
| 353 | */ |
||
| 354 | public function delete() |
||
| 358 | |||
| 359 | /** |
||
| 360 | * Uses _bulk to delete documents from the server. |
||
| 361 | * |
||
| 362 | * @param array|Document[] $docs Array of Elastica\Document |
||
| 363 | * |
||
| 364 | * @return ResponseSet |
||
| 365 | * |
||
| 366 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html |
||
| 367 | */ |
||
| 368 | public function deleteDocuments(array $docs) |
||
| 376 | |||
| 377 | /** |
||
| 378 | * Force merges index. |
||
| 379 | * |
||
| 380 | * Detailed arguments can be found here in the link |
||
| 381 | * |
||
| 382 | * @param array $args OPTIONAL Additional arguments |
||
| 383 | * |
||
| 384 | * @return Response |
||
| 385 | * |
||
| 386 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-forcemerge.html |
||
| 387 | */ |
||
| 388 | public function forcemerge($args = []) |
||
| 395 | |||
| 396 | /** |
||
| 397 | * Refreshes the index. |
||
| 398 | * |
||
| 399 | * @return Response Response object |
||
| 400 | * |
||
| 401 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-refresh.html |
||
| 402 | */ |
||
| 403 | public function refresh() |
||
| 407 | |||
| 408 | /** |
||
| 409 | * Creates a new index with the given arguments. |
||
| 410 | * |
||
| 411 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-create-index.html |
||
| 412 | * |
||
| 413 | * @param array $args OPTIONAL Arguments to use |
||
| 414 | * @param bool|array $options OPTIONAL |
||
| 415 | * bool=> Deletes index first if already exists (default = false). |
||
| 416 | * array => Associative array of options (option=>value) |
||
| 417 | * |
||
| 418 | * @throws InvalidException |
||
| 419 | * @throws \Elastica\Exception\ResponseException |
||
| 420 | * |
||
| 421 | * @return Response Server response |
||
| 422 | */ |
||
| 423 | public function create(array $args = [], $options = null) |
||
| 453 | |||
| 454 | /** |
||
| 455 | * Checks if the given index is already created. |
||
| 456 | * |
||
| 457 | * @return bool True if index exists |
||
| 458 | */ |
||
| 459 | public function exists(): bool |
||
| 465 | |||
| 466 | /** |
||
| 467 | * @param string|array|Query $query |
||
| 468 | * @param int|array $options |
||
| 469 | * @param BuilderInterface $builder |
||
| 470 | * |
||
| 471 | * @return Search |
||
| 472 | */ |
||
| 473 | public function createSearch($query = '', $options = null, BuilderInterface $builder = null) |
||
| 481 | |||
| 482 | /** |
||
| 483 | * Searches in this index. |
||
| 484 | * |
||
| 485 | * @param string|array|Query $query Array with all query data inside or a Elastica\Query object |
||
| 486 | * @param int|array $options OPTIONAL Limit or associative array of options (option=>value) |
||
| 487 | * @param string $method OPTIONAL Request method (use const's) (default = Request::POST) |
||
| 488 | * |
||
| 489 | * @return ResultSet with all results inside |
||
| 490 | * |
||
| 491 | * @see \Elastica\SearchableInterface::search |
||
| 492 | */ |
||
| 493 | public function search($query = '', $options = null, $method = Request::POST) |
||
| 499 | |||
| 500 | /** |
||
| 501 | * Counts results of query. |
||
| 502 | * |
||
| 503 | * @param string|array|Query $query Array with all query data inside or a Elastica\Query object |
||
| 504 | * @param string $method OPTIONAL Request method (use const's) (default = Request::POST) |
||
| 505 | * |
||
| 506 | * @return int number of documents matching the query |
||
| 507 | * |
||
| 508 | * @see \Elastica\SearchableInterface::count |
||
| 509 | */ |
||
| 510 | public function count($query = '', $method = Request::POST) |
||
| 516 | |||
| 517 | /** |
||
| 518 | * Opens an index. |
||
| 519 | * |
||
| 520 | * @return Response Response object |
||
| 521 | * |
||
| 522 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-open-close.html |
||
| 523 | */ |
||
| 524 | public function open() |
||
| 528 | |||
| 529 | /** |
||
| 530 | * Closes the index. |
||
| 531 | * |
||
| 532 | * @return Response Response object |
||
| 533 | * |
||
| 534 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-open-close.html |
||
| 535 | */ |
||
| 536 | public function close() |
||
| 540 | |||
| 541 | /** |
||
| 542 | * Returns the index name. |
||
| 543 | * |
||
| 544 | * @return string Index name |
||
| 545 | */ |
||
| 546 | public function getName(): string |
||
| 550 | |||
| 551 | /** |
||
| 552 | * Returns index client. |
||
| 553 | * |
||
| 554 | * @return \Elastica\Client Index client object |
||
| 555 | */ |
||
| 556 | public function getClient() |
||
| 560 | |||
| 561 | /** |
||
| 562 | * Adds an alias to the current index. |
||
| 563 | * |
||
| 564 | * @param string $name Alias name |
||
| 565 | * @param bool $replace OPTIONAL If set, an existing alias will be replaced |
||
| 566 | * |
||
| 567 | * @return Response Response |
||
| 568 | * |
||
| 569 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html |
||
| 570 | */ |
||
| 571 | public function addAlias($name, $replace = false) |
||
| 589 | |||
| 590 | /** |
||
| 591 | * Removes an alias pointing to the current index. |
||
| 592 | * |
||
| 593 | * @param string $name Alias name |
||
| 594 | * |
||
| 595 | * @return Response Response |
||
| 596 | * |
||
| 597 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html |
||
| 598 | */ |
||
| 599 | public function removeAlias($name) |
||
| 606 | |||
| 607 | /** |
||
| 608 | * Returns all index aliases. |
||
| 609 | * |
||
| 610 | * @return array Aliases |
||
| 611 | */ |
||
| 612 | public function getAliases() |
||
| 630 | |||
| 631 | /** |
||
| 632 | * Checks if the index has the given alias. |
||
| 633 | * |
||
| 634 | * @param string $name Alias name |
||
| 635 | * |
||
| 636 | * @return bool |
||
| 637 | */ |
||
| 638 | public function hasAlias($name) |
||
| 642 | |||
| 643 | /** |
||
| 644 | * Clears the cache of an index. |
||
| 645 | * |
||
| 646 | * @return Response Response object |
||
| 647 | * |
||
| 648 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-clearcache.html |
||
| 649 | */ |
||
| 650 | public function clearCache() |
||
| 655 | |||
| 656 | /** |
||
| 657 | * Flushes the index to storage. |
||
| 658 | * |
||
| 659 | * @param array $options |
||
| 660 | * |
||
| 661 | * @return Response Response object |
||
| 662 | * |
||
| 663 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-flush.html |
||
| 664 | */ |
||
| 665 | public function flush(array $options = []) |
||
| 672 | |||
| 673 | /** |
||
| 674 | * Can be used to change settings during runtime. One example is to use it for bulk updating. |
||
| 675 | * |
||
| 676 | * @param array $data Data array |
||
| 677 | * |
||
| 678 | * @return Response Response object |
||
| 679 | * |
||
| 680 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html |
||
| 681 | */ |
||
| 682 | public function setSettings(array $data) |
||
| 689 | |||
| 690 | /** |
||
| 691 | * Makes calls to the elasticsearch server based on this index. |
||
| 692 | * |
||
| 693 | * @param string $path Path to call |
||
| 694 | * @param string $method Rest method to use (GET, POST, DELETE, PUT) |
||
| 695 | * @param array|string $data OPTIONAL Arguments as array or encoded string |
||
| 696 | * @param array $query OPTIONAL Query params |
||
| 697 | * |
||
| 698 | * @return Response Response object |
||
| 699 | */ |
||
| 700 | public function request($path, $method, $data = [], array $query = []) |
||
| 706 | |||
| 707 | /** |
||
| 708 | * Makes calls to the elasticsearch server with usage official client Endpoint based on this index. |
||
| 709 | * |
||
| 710 | * @param AbstractEndpoint $endpoint |
||
| 711 | * |
||
| 712 | * @return Response |
||
| 713 | */ |
||
| 714 | public function requestEndpoint(AbstractEndpoint $endpoint) |
||
| 721 | |||
| 722 | /** |
||
| 723 | * Run the analysis on the index. |
||
| 724 | * |
||
| 725 | * @param array $body request body for the `_analyze` API, see API documentation for the requried properties |
||
| 726 | * @param array $args OPTIONAL Additional arguments |
||
| 727 | * |
||
| 728 | * @return array Server response |
||
| 729 | * |
||
| 730 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-analyze.html |
||
| 731 | */ |
||
| 732 | public function analyze(array $body, $args = []) |
||
| 748 | |||
| 749 | /** |
||
| 750 | * Update document, using update script. |
||
| 751 | * |
||
| 752 | * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html |
||
| 753 | * |
||
| 754 | * @param Document|AbstractScript $data Document or Script with update data |
||
| 755 | * @param array $options array of query params to use for query |
||
| 756 | * |
||
| 757 | * @throws InvalidException |
||
| 758 | * |
||
| 759 | * @return Response |
||
| 760 | */ |
||
| 761 | public function updateDocument($data, array $options = []) |
||
| 773 | } |
||
| 774 |
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.