Complex classes like 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 Cache, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 14 | class Cache { |
||
| 15 | |||
| 16 | /** |
||
| 17 | * Cache storage object |
||
| 18 | * @var StorageInterface |
||
| 19 | */ |
||
| 20 | protected $storage; |
||
| 21 | |||
| 22 | /** |
||
| 23 | * Caching is enabled |
||
| 24 | * @var bool |
||
| 25 | */ |
||
| 26 | protected $enabled = true; |
||
| 27 | |||
| 28 | /** |
||
| 29 | * Key name encryption |
||
| 30 | * @var bool |
||
| 31 | */ |
||
| 32 | protected $encryptKeys = true; |
||
| 33 | |||
| 34 | /** |
||
| 35 | * Cache values information |
||
| 36 | * @var Info |
||
| 37 | */ |
||
| 38 | protected $info; |
||
| 39 | |||
| 40 | /** |
||
| 41 | * Read key names |
||
| 42 | * @var array |
||
| 43 | */ |
||
| 44 | protected $readKeys = array(); |
||
| 45 | |||
| 46 | /** |
||
| 47 | * System reserved info key |
||
| 48 | * @var string |
||
| 49 | */ |
||
| 50 | protected $infoKey = '_system.info'; |
||
| 51 | |||
| 52 | /** |
||
| 53 | * Initialised (-1: not yet, 0: in progress, 1: initialised) |
||
| 54 | * @var int |
||
| 55 | */ |
||
| 56 | protected $initialised = -1; |
||
| 57 | |||
| 58 | const STORE_METHOD_SERIALIZE = 1; |
||
| 59 | const STORE_METHOD_JSON = 2; |
||
| 60 | |||
| 61 | /** |
||
| 62 | * Constructor |
||
| 63 | * |
||
| 64 | * @param StorageInterface $storage |
||
| 65 | * @param array $options |
||
| 66 | */ |
||
| 67 | public function __construct(StorageInterface $storage, array $options = array()) { |
||
| 73 | |||
| 74 | /** |
||
| 75 | * Initialise (lazy) |
||
| 76 | */ |
||
| 77 | public function init() { |
||
| 94 | |||
| 95 | /** |
||
| 96 | * Handles cached value expiration |
||
| 97 | * |
||
| 98 | * @param array $data |
||
| 99 | * @param string $key |
||
| 100 | * |
||
| 101 | * @return boolean |
||
| 102 | */ |
||
| 103 | protected function handleExpiration($data, $key) { |
||
| 112 | |||
| 113 | /** |
||
| 114 | * Gets Cache info |
||
| 115 | * |
||
| 116 | * @param $name Cache key |
||
| 117 | * |
||
| 118 | * @return array |
||
| 119 | */ |
||
| 120 | public function getInfo($name = '') { |
||
| 128 | |||
| 129 | /** |
||
| 130 | * Check if Cache is enabled |
||
| 131 | * |
||
| 132 | * @return bool |
||
| 133 | */ |
||
| 134 | public function isEnabled() { |
||
| 137 | |||
| 138 | /** |
||
| 139 | * Enable/disable caching |
||
| 140 | * |
||
| 141 | * @param bool $enabled |
||
| 142 | */ |
||
| 143 | public function setEnabled($enabled) { |
||
| 146 | |||
| 147 | /** |
||
| 148 | * Checks if the specified name in cache exists |
||
| 149 | * |
||
| 150 | * @param string $name cache name |
||
| 151 | * |
||
| 152 | * @return bool |
||
| 153 | */ |
||
| 154 | public function has($name) { |
||
| 163 | |||
| 164 | /** |
||
| 165 | * Deletes the specified cache or each one if '' given |
||
| 166 | * |
||
| 167 | * @param string $name cache name |
||
| 168 | * |
||
| 169 | * @return bool |
||
| 170 | */ |
||
| 171 | public function delete($name = '') { |
||
| 188 | |||
| 189 | /** |
||
| 190 | * Flush all from cache |
||
| 191 | * |
||
| 192 | * @return bool |
||
| 193 | */ |
||
| 194 | public function flush() { |
||
| 197 | |||
| 198 | /** |
||
| 199 | * Stores the variable to the $name cache |
||
| 200 | * |
||
| 201 | * @param string $name cache name |
||
| 202 | * @param mixed $val variable to be stored |
||
| 203 | * @param bool $compressed Compressed storage |
||
| 204 | * @param int|string $expiry Expires in the given seconds (0:never) or the time defined by valid date string (eg. '2014-10-01' or '1week' or '2hours') |
||
| 205 | * @param string $storeMethod Storing method (serialize|json) |
||
| 206 | * |
||
| 207 | * @return bool |
||
| 208 | */ |
||
| 209 | public function store($name, $val, $compressed = false, $expiry = 0, $storeMethod = self::STORE_METHOD_SERIALIZE) { |
||
| 236 | |||
| 237 | /** |
||
| 238 | * Extracts expiry by string |
||
| 239 | * |
||
| 240 | * @param mixed $expiry |
||
| 241 | * |
||
| 242 | * @return int |
||
| 243 | */ |
||
| 244 | protected function extractExpiryDate($expiry) { |
||
| 259 | |||
| 260 | /** |
||
| 261 | * Retrieves the content of $name cache |
||
| 262 | * |
||
| 263 | * @param string $name cache name |
||
| 264 | * @param mixed $default |
||
| 265 | * |
||
| 266 | * @return mixed |
||
| 267 | */ |
||
| 268 | public function get($name, $default = null) { |
||
| 290 | |||
| 291 | /** |
||
| 292 | * Extract cached value parameters |
||
| 293 | * |
||
| 294 | * @param string $name |
||
| 295 | * |
||
| 296 | * @return array |
||
| 297 | */ |
||
| 298 | protected function extractParameters($name) { |
||
| 303 | |||
| 304 | /** |
||
| 305 | * Attempts to get a value and if not exists store the given default variable |
||
| 306 | * |
||
| 307 | * @param string $name cache name |
||
| 308 | * @param mixed $default default value |
||
| 309 | * @param bool $compressed Compressed storage |
||
| 310 | * @param int|string $expiry Expires in the given seconds (0:never) or the time defined by valid date string (eg. '2014-10-01' or '1week' or '2hours') |
||
| 311 | * @param int $storeMethod Storing method (serialize|json) |
||
| 312 | * |
||
| 313 | * @return mixed |
||
| 314 | */ |
||
| 315 | public function getOrStore($name, $default, $compressed = false, $expiry = 0, $storeMethod = self::STORE_METHOD_SERIALIZE) { |
||
| 323 | |||
| 324 | /** |
||
| 325 | * Retrieves and deletes value from cache |
||
| 326 | * |
||
| 327 | * @param string $name |
||
| 328 | * |
||
| 329 | * @return mixed |
||
| 330 | */ |
||
| 331 | public function pull($name) { |
||
| 336 | |||
| 337 | /** |
||
| 338 | * Retrieves information of Cache state |
||
| 339 | * |
||
| 340 | * @param bool $getFields |
||
| 341 | * |
||
| 342 | * @return array|bool |
||
| 343 | */ |
||
| 344 | public function info($getFields = false) { |
||
| 351 | |||
| 352 | /** |
||
| 353 | * Encodes variable with the specified method |
||
| 354 | * |
||
| 355 | * @param mixed $var Variable |
||
| 356 | * @param int $storeMethod serialize|json |
||
| 357 | * |
||
| 358 | * @return mixed |
||
| 359 | */ |
||
| 360 | protected function encode($var, $storeMethod = self::STORE_METHOD_SERIALIZE) { |
||
| 371 | |||
| 372 | /** |
||
| 373 | * Decodes variable with the specified method |
||
| 374 | * |
||
| 375 | * @param mixed $var Variable |
||
| 376 | * @param int $storeMethod serialize|json |
||
| 377 | * |
||
| 378 | * @return mixed |
||
| 379 | */ |
||
| 380 | protected function decode($var, $storeMethod = self::STORE_METHOD_SERIALIZE) { |
||
| 396 | |||
| 397 | /** |
||
| 398 | * Encrypts key |
||
| 399 | * |
||
| 400 | * @param string $key |
||
| 401 | * |
||
| 402 | * @return string |
||
| 403 | */ |
||
| 404 | protected function encryptKey($key) { |
||
| 407 | |||
| 408 | /** |
||
| 409 | * Gets cache hits |
||
| 410 | * |
||
| 411 | * @return int |
||
| 412 | */ |
||
| 413 | public function getHits() { |
||
| 420 | |||
| 421 | /** |
||
| 422 | * Gets cache misses |
||
| 423 | * |
||
| 424 | * @return int |
||
| 425 | */ |
||
| 426 | public function getMisses() { |
||
| 433 | |||
| 434 | /** |
||
| 435 | * Stores cache values expiral information into cache |
||
| 436 | */ |
||
| 437 | public function writeExpirals() { |
||
| 443 | |||
| 444 | /** |
||
| 445 | * Gets expiry information of a cached value (0: never) |
||
| 446 | * |
||
| 447 | * @param string $name Cache name |
||
| 448 | * @param string $format Date format |
||
| 449 | * |
||
| 450 | * @return string |
||
| 451 | */ |
||
| 452 | public function getExpiry($name, $format = 'U') { |
||
| 459 | |||
| 460 | /** |
||
| 461 | * Calculates Time To Live |
||
| 462 | * |
||
| 463 | * @param string $name |
||
| 464 | * |
||
| 465 | * @return int |
||
| 466 | */ |
||
| 467 | public function getTTL($name) { |
||
| 471 | |||
| 472 | /** |
||
| 473 | * Modifies expiry by setting Time To Live |
||
| 474 | * |
||
| 475 | * @param string $name |
||
| 476 | * @param int $ttl |
||
| 477 | */ |
||
| 478 | public function setTTL($name, $ttl) { |
||
| 485 | |||
| 486 | /** |
||
| 487 | * Modifies expiry |
||
| 488 | * |
||
| 489 | * @param string $name |
||
| 490 | * @param mixed $expiry |
||
| 491 | */ |
||
| 492 | public function setExpiry($name, $expiry) { |
||
| 497 | |||
| 498 | /** |
||
| 499 | * Gets created (first write) time of a cached value |
||
| 500 | * |
||
| 501 | * @param string $name Cache name |
||
| 502 | * @param string $format Date format |
||
| 503 | * |
||
| 504 | * @return string |
||
| 505 | */ |
||
| 506 | public function getCreated($name, $format = 'U') { |
||
| 509 | |||
| 510 | /** |
||
| 511 | * Gets last access (either read or write) time of a cached value |
||
| 512 | * |
||
| 513 | * @param string $name Cache name |
||
| 514 | * @param string $format Date format |
||
| 515 | * |
||
| 516 | * @return string |
||
| 517 | */ |
||
| 518 | public function getLastAccess($name, $format = 'U') { |
||
| 521 | |||
| 522 | /** |
||
| 523 | * Gets last read time of a cached value |
||
| 524 | * |
||
| 525 | * @param string $name Cache name |
||
| 526 | * @param string $format Date format |
||
| 527 | * |
||
| 528 | * @return string |
||
| 529 | */ |
||
| 530 | public function getLastRead($name, $format = 'U') { |
||
| 533 | |||
| 534 | /** |
||
| 535 | * Gets last write time of a cached value |
||
| 536 | * |
||
| 537 | * @param string $name Cache name |
||
| 538 | * @param string $format Date format |
||
| 539 | * |
||
| 540 | * @return string |
||
| 541 | */ |
||
| 542 | public function getLastWrite($name, $format = 'U') { |
||
| 545 | |||
| 546 | /** |
||
| 547 | * Gets read count of a cached value |
||
| 548 | * |
||
| 549 | * @param string $name Cache name |
||
| 550 | * |
||
| 551 | * @return int |
||
| 552 | */ |
||
| 553 | public function getReadCount($name) { |
||
| 556 | |||
| 557 | /** |
||
| 558 | * Gets write count of a cached value |
||
| 559 | * |
||
| 560 | * @param string $name Cache name |
||
| 561 | * |
||
| 562 | * @return int |
||
| 563 | */ |
||
| 564 | public function getWriteCount($name) { |
||
| 567 | |||
| 568 | /** |
||
| 569 | * Gets all cache key names |
||
| 570 | * |
||
| 571 | * @return array |
||
| 572 | */ |
||
| 573 | public function getKeys() { |
||
| 580 | |||
| 581 | /** |
||
| 582 | * Gets cache key names which already read |
||
| 583 | * |
||
| 584 | * @return array |
||
| 585 | */ |
||
| 586 | public function getReadKeys() { |
||
| 589 | |||
| 590 | /** |
||
| 591 | * Gets storage object |
||
| 592 | * |
||
| 593 | * @return StorageInterface |
||
| 594 | */ |
||
| 595 | public function getStorage() { |
||
| 598 | |||
| 599 | /** |
||
| 600 | * Retrieves key encryption |
||
| 601 | * |
||
| 602 | * @return bool |
||
| 603 | */ |
||
| 604 | public function getEncryptKeys() { |
||
| 607 | |||
| 608 | /** |
||
| 609 | * Sets key encryption |
||
| 610 | * |
||
| 611 | * @param bool $encryptKeys |
||
| 612 | */ |
||
| 613 | public function setEncryptKeys($encryptKeys) { |
||
| 616 | |||
| 617 | /** |
||
| 618 | * Sets cache storage |
||
| 619 | * |
||
| 620 | * @param StorageInterface $storage |
||
| 621 | */ |
||
| 622 | public function setStorage(StorageInterface $storage) { |
||
| 625 | |||
| 626 | /** |
||
| 627 | * Destructor |
||
| 628 | */ |
||
| 629 | public function __destruct() { |
||
| 632 | |||
| 633 | /** |
||
| 634 | * Sets a tagged cache value |
||
| 635 | * |
||
| 636 | * @param string $name cache name |
||
| 637 | * @param mixed $val variable to be stored |
||
| 638 | * @param array $tags tags |
||
| 639 | * @param bool $compressed Compressed storage |
||
| 640 | * @param int|string $expiry Expires in the given seconds (0:never) or the time defined by valid date string (eg. '2014-10-01' or '1week' or '2hours') |
||
| 641 | * @param int $storeMethod Storing method (serialize|json) |
||
| 642 | * |
||
| 643 | * @return bool |
||
| 644 | */ |
||
| 645 | public function storeTagged($name, $val, $tags, $compressed = false, $expiry = 0, $storeMethod = self::STORE_METHOD_SERIALIZE) { |
||
| 652 | |||
| 653 | /** |
||
| 654 | * Gets tagged cache values |
||
| 655 | * |
||
| 656 | * @param array $tags |
||
| 657 | * |
||
| 658 | * @return array |
||
| 659 | */ |
||
| 660 | public function getTagged($tags) { |
||
| 674 | |||
| 675 | /** |
||
| 676 | * Gets tags of a cached variable |
||
| 677 | * |
||
| 678 | * @param string $key |
||
| 679 | * |
||
| 680 | * @return array |
||
| 681 | */ |
||
| 682 | public function getTags($key) { |
||
| 692 | |||
| 693 | /** |
||
| 694 | * Sets tags of a cached variable |
||
| 695 | * |
||
| 696 | * @param string $name |
||
| 697 | * @param array $tags |
||
| 698 | * |
||
| 699 | * @return array |
||
| 700 | */ |
||
| 701 | public function setTags($name, $tags) { |
||
| 708 | |||
| 709 | /** |
||
| 710 | * Adds tags for a cached variable |
||
| 711 | * |
||
| 712 | * @param string $name |
||
| 713 | * @param array $tags |
||
| 714 | * |
||
| 715 | * @return array |
||
| 716 | */ |
||
| 717 | public function addTags($name, $tags) { |
||
| 725 | |||
| 726 | /** |
||
| 727 | * Deletes cache values matching the given tags |
||
| 728 | * |
||
| 729 | * @param array $tags |
||
| 730 | * |
||
| 731 | * @return array |
||
| 732 | */ |
||
| 733 | public function deleteTagged($tags) { |
||
| 743 | |||
| 744 | /** |
||
| 745 | * Gets all tags currently in use |
||
| 746 | * |
||
| 747 | * @return array |
||
| 748 | */ |
||
| 749 | public function getAllTags() { |
||
| 762 | |||
| 763 | /** |
||
| 764 | * Prepares tags parameter |
||
| 765 | * |
||
| 766 | * @param array|string $tags |
||
| 767 | */ |
||
| 768 | protected function prepareTags(&$tags) { |
||
| 774 | |||
| 775 | /** |
||
| 776 | * Checks if cache value info can be modified (cache is enabled and value exists) |
||
| 777 | * |
||
| 778 | * @param string $name |
||
| 779 | * |
||
| 780 | * @return boolean |
||
| 781 | */ |
||
| 782 | protected function canModify($name) { |
||
| 789 | |||
| 790 | /** |
||
| 791 | * Processes default value |
||
| 792 | * |
||
| 793 | * @param \Closure|mixed $default |
||
| 794 | * |
||
| 795 | * @return mixed |
||
| 796 | */ |
||
| 797 | protected function processDefault($default) { |
||
| 800 | |||
| 801 | } |
||
| 802 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignorePhpDoc annotation to the duplicate definition and it will be ignored.