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 WP_Object_Cache 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 WP_Object_Cache, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 290 | class WP_Object_Cache { |
||
| 291 | |||
| 292 | /** |
||
| 293 | * Holds the cached objects. |
||
| 294 | * |
||
| 295 | * @since 2.0.0 |
||
| 296 | * @access private |
||
| 297 | * @var array |
||
| 298 | */ |
||
| 299 | private $cache = array(); |
||
| 300 | |||
| 301 | /** |
||
| 302 | * The amount of times the cache data was already stored in the cache. |
||
| 303 | * |
||
| 304 | * @since 2.5.0 |
||
| 305 | * @access private |
||
| 306 | * @var int |
||
| 307 | */ |
||
| 308 | private $cache_hits = 0; |
||
| 309 | |||
| 310 | /** |
||
| 311 | * Amount of times the cache did not have the request in cache. |
||
| 312 | * |
||
| 313 | * @since 2.0.0 |
||
| 314 | * @access public |
||
| 315 | * @var int |
||
| 316 | */ |
||
| 317 | public $cache_misses = 0; |
||
| 318 | |||
| 319 | /** |
||
| 320 | * List of global cache groups. |
||
| 321 | * |
||
| 322 | * @since 3.0.0 |
||
| 323 | * @access protected |
||
| 324 | * @var array |
||
| 325 | */ |
||
| 326 | protected $global_groups = array(); |
||
| 327 | |||
| 328 | /** |
||
| 329 | * The blog prefix to prepend to keys in non-global groups. |
||
| 330 | * |
||
| 331 | * @since 3.5.0 |
||
| 332 | * @access private |
||
| 333 | * @var int |
||
| 334 | */ |
||
| 335 | private $blog_prefix; |
||
| 336 | |||
| 337 | /** |
||
| 338 | * Holds the value of is_multisite(). |
||
| 339 | * |
||
| 340 | * @since 3.5.0 |
||
| 341 | * @access private |
||
| 342 | * @var bool |
||
| 343 | */ |
||
| 344 | private $multisite; |
||
| 345 | |||
| 346 | /** |
||
| 347 | * Makes private properties readable for backward compatibility. |
||
| 348 | * |
||
| 349 | * @since 4.0.0 |
||
| 350 | * @access public |
||
| 351 | * |
||
| 352 | * @param string $name Property to get. |
||
| 353 | * @return mixed Property. |
||
| 354 | */ |
||
| 355 | public function __get( $name ) { |
||
| 358 | |||
| 359 | /** |
||
| 360 | * Makes private properties settable for backward compatibility. |
||
| 361 | * |
||
| 362 | * @since 4.0.0 |
||
| 363 | * @access public |
||
| 364 | * |
||
| 365 | * @param string $name Property to set. |
||
| 366 | * @param mixed $value Property value. |
||
| 367 | * @return mixed Newly-set property. |
||
| 368 | */ |
||
| 369 | public function __set( $name, $value ) { |
||
| 372 | |||
| 373 | /** |
||
| 374 | * Makes private properties checkable for backward compatibility. |
||
| 375 | * |
||
| 376 | * @since 4.0.0 |
||
| 377 | * @access public |
||
| 378 | * |
||
| 379 | * @param string $name Property to check if set. |
||
| 380 | * @return bool Whether the property is set. |
||
| 381 | */ |
||
| 382 | public function __isset( $name ) { |
||
| 385 | |||
| 386 | /** |
||
| 387 | * Makes private properties un-settable for backward compatibility. |
||
| 388 | * |
||
| 389 | * @since 4.0.0 |
||
| 390 | * @access public |
||
| 391 | * |
||
| 392 | * @param string $name Property to unset. |
||
| 393 | */ |
||
| 394 | public function __unset( $name ) { |
||
| 397 | |||
| 398 | /** |
||
| 399 | * Adds data to the cache if it doesn't already exist. |
||
| 400 | * |
||
| 401 | * @since 2.0.0 |
||
| 402 | * @access public |
||
| 403 | * |
||
| 404 | * @uses WP_Object_Cache::_exists() Checks to see if the cache already has data. |
||
| 405 | * @uses WP_Object_Cache::set() Sets the data after the checking the cache |
||
| 406 | * contents existence. |
||
| 407 | * |
||
| 408 | * @param int|string $key What to call the contents in the cache. |
||
| 409 | * @param mixed $data The contents to store in the cache. |
||
| 410 | * @param string $group Optional. Where to group the cache contents. Default 'default'. |
||
| 411 | * @param int $expire Optional. When to expire the cache contents. Default 0 (no expiration). |
||
| 412 | * @return bool False if cache key and group already exist, true on success |
||
| 413 | */ |
||
| 414 | View Code Duplication | public function add( $key, $data, $group = 'default', $expire = 0 ) { |
|
| 430 | |||
| 431 | /** |
||
| 432 | * Sets the list of global cache groups. |
||
| 433 | * |
||
| 434 | * @since 3.0.0 |
||
| 435 | * @access public |
||
| 436 | * |
||
| 437 | * @param array $groups List of groups that are global. |
||
| 438 | */ |
||
| 439 | public function add_global_groups( $groups ) { |
||
| 445 | |||
| 446 | /** |
||
| 447 | * Decrements numeric cache item's value. |
||
| 448 | * |
||
| 449 | * @since 3.3.0 |
||
| 450 | * @access public |
||
| 451 | * |
||
| 452 | * @param int|string $key The cache key to decrement. |
||
| 453 | * @param int $offset Optional. The amount by which to decrement the item's value. Default 1. |
||
| 454 | * @param string $group Optional. The group the key is in. Default 'default'. |
||
| 455 | * @return false|int False on failure, the item's new value on success. |
||
| 456 | */ |
||
| 457 | View Code Duplication | public function decr( $key, $offset = 1, $group = 'default' ) { |
|
| 479 | |||
| 480 | /** |
||
| 481 | * Removes the contents of the cache key in the group. |
||
| 482 | * |
||
| 483 | * If the cache key does not exist in the group, then nothing will happen. |
||
| 484 | * |
||
| 485 | * @since 2.0.0 |
||
| 486 | * @access public |
||
| 487 | * |
||
| 488 | * @param int|string $key What the contents in the cache are called. |
||
| 489 | * @param string $group Optional. Where the cache contents are grouped. Default 'default'. |
||
| 490 | * @param bool $deprecated Optional. Unused. Default false. |
||
| 491 | * @return bool False if the contents weren't deleted and true on success. |
||
| 492 | */ |
||
| 493 | public function delete( $key, $group = 'default', $deprecated = false ) { |
||
| 506 | |||
| 507 | /** |
||
| 508 | * Clears the object cache of all data. |
||
| 509 | * |
||
| 510 | * @since 2.0.0 |
||
| 511 | * @access public |
||
| 512 | * |
||
| 513 | * @return true Always returns true. |
||
| 514 | */ |
||
| 515 | public function flush() { |
||
| 520 | |||
| 521 | /** |
||
| 522 | * Retrieves the cache contents, if it exists. |
||
| 523 | * |
||
| 524 | * The contents will be first attempted to be retrieved by searching by the |
||
| 525 | * key in the cache group. If the cache is hit (success) then the contents |
||
| 526 | * are returned. |
||
| 527 | * |
||
| 528 | * On failure, the number of cache misses will be incremented. |
||
| 529 | * |
||
| 530 | * @since 2.0.0 |
||
| 531 | * @access public |
||
| 532 | * |
||
| 533 | * @param int|string $key What the contents in the cache are called. |
||
| 534 | * @param string $group Optional. Where the cache contents are grouped. Default 'default'. |
||
| 535 | * @param string $force Optional. Unused. Whether to force a refetch rather than relying on the local |
||
| 536 | * cache. Default false. |
||
| 537 | * @param bool $found Optional. Whether the key was found in the cache. Disambiguates a return of |
||
| 538 | * false, a storable value. Passed by reference. Default null. |
||
| 539 | * @return false|mixed False on failure to retrieve contents or the cache contents on success. |
||
| 540 | */ |
||
| 541 | public function get( $key, $group = 'default', $force = false, &$found = null ) { |
||
| 561 | |||
| 562 | /** |
||
| 563 | * Increments numeric cache item's value. |
||
| 564 | * |
||
| 565 | * @since 3.3.0 |
||
| 566 | * @access public |
||
| 567 | * |
||
| 568 | * @param int|string $key The cache key to increment |
||
| 569 | * @param int $offset Optional. The amount by which to increment the item's value. Default 1. |
||
| 570 | * @param string $group Optional. The group the key is in. Default 'default'. |
||
| 571 | * @return false|int False on failure, the item's new value on success. |
||
| 572 | */ |
||
| 573 | View Code Duplication | public function incr( $key, $offset = 1, $group = 'default' ) { |
|
| 595 | |||
| 596 | /** |
||
| 597 | * Replaces the contents in the cache, if contents already exist. |
||
| 598 | * |
||
| 599 | * @since 2.0.0 |
||
| 600 | * @access public |
||
| 601 | * |
||
| 602 | * @see WP_Object_Cache::set() |
||
| 603 | * |
||
| 604 | * @param int|string $key What to call the contents in the cache. |
||
| 605 | * @param mixed $data The contents to store in the cache. |
||
| 606 | * @param string $group Optional. Where to group the cache contents. Default 'default'. |
||
| 607 | * @param int $expire Optional. When to expire the cache contents. Default 0 (no expiration). |
||
| 608 | * @return bool False if not exists, true if contents were replaced. |
||
| 609 | */ |
||
| 610 | View Code Duplication | public function replace( $key, $data, $group = 'default', $expire = 0 ) { |
|
| 623 | |||
| 624 | /** |
||
| 625 | * Resets cache keys. |
||
| 626 | * |
||
| 627 | * @since 3.0.0 |
||
| 628 | * @access public |
||
| 629 | * |
||
| 630 | * @deprecated 3.5.0 Use switch_to_blog() |
||
| 631 | * @see switch_to_blog() |
||
| 632 | */ |
||
| 633 | public function reset() { |
||
| 642 | |||
| 643 | /** |
||
| 644 | * Sets the data contents into the cache. |
||
| 645 | * |
||
| 646 | * The cache contents is grouped by the $group parameter followed by the |
||
| 647 | * $key. This allows for duplicate ids in unique groups. Therefore, naming of |
||
| 648 | * the group should be used with care and should follow normal function |
||
| 649 | * naming guidelines outside of core WordPress usage. |
||
| 650 | * |
||
| 651 | * The $expire parameter is not used, because the cache will automatically |
||
| 652 | * expire for each time a page is accessed and PHP finishes. The method is |
||
| 653 | * more for cache plugins which use files. |
||
| 654 | * |
||
| 655 | * @since 2.0.0 |
||
| 656 | * @access public |
||
| 657 | * |
||
| 658 | * @param int|string $key What to call the contents in the cache. |
||
| 659 | * @param mixed $data The contents to store in the cache. |
||
| 660 | * @param string $group Optional. Where to group the cache contents. Default 'default'. |
||
| 661 | * @param int $expire Not Used. |
||
| 662 | * @return true Always returns true. |
||
| 663 | */ |
||
| 664 | public function set( $key, $data, $group = 'default', $expire = 0 ) { |
||
| 677 | |||
| 678 | /** |
||
| 679 | * Echoes the stats of the caching. |
||
| 680 | * |
||
| 681 | * Gives the cache hits, and cache misses. Also prints every cached group, |
||
| 682 | * key and the data. |
||
| 683 | * |
||
| 684 | * @since 2.0.0 |
||
| 685 | * @access public |
||
| 686 | */ |
||
| 687 | public function stats() { |
||
| 698 | |||
| 699 | /** |
||
| 700 | * Switches the internal blog ID. |
||
| 701 | * |
||
| 702 | * This changes the blog ID used to create keys in blog specific groups. |
||
| 703 | * |
||
| 704 | * @since 3.5.0 |
||
| 705 | * @access public |
||
| 706 | * |
||
| 707 | * @param int $blog_id Blog ID. |
||
| 708 | */ |
||
| 709 | public function switch_to_blog( $blog_id ) { |
||
| 713 | |||
| 714 | /** |
||
| 715 | * Serves as a utility function to determine whether a key exists in the cache. |
||
| 716 | * |
||
| 717 | * @since 3.4.0 |
||
| 718 | * @access protected |
||
| 719 | * |
||
| 720 | * @param int|string $key Cache key to check for existence. |
||
| 721 | * @param string $group Cache group for the key existence check. |
||
| 722 | * @return bool Whether the key exists in the cache for the given group. |
||
| 723 | */ |
||
| 724 | protected function _exists( $key, $group ) { |
||
| 727 | |||
| 728 | /** |
||
| 729 | * Sets up object properties; PHP 5 style constructor. |
||
| 730 | * |
||
| 731 | * @since 2.0.8 |
||
| 732 | * |
||
| 733 | * @global int $blog_id Global blog ID. |
||
| 734 | */ |
||
| 735 | public function __construct() { |
||
| 748 | |||
| 749 | /** |
||
| 750 | * Saves the object cache before object is completely destroyed. |
||
| 751 | * |
||
| 752 | * Called upon object destruction, which should be when PHP ends. |
||
| 753 | * |
||
| 754 | * @since 2.0.8 |
||
| 755 | * |
||
| 756 | * @return true Always returns true. |
||
| 757 | */ |
||
| 758 | public function __destruct() { |
||
| 761 | } |
||
| 762 |
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.