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 |
||
20 | class Cache implements iCache |
||
21 | { |
||
22 | /** |
||
23 | * @var iAdapter |
||
24 | */ |
||
25 | protected $adapter; |
||
26 | |||
27 | /** |
||
28 | * @var iSerializer |
||
29 | */ |
||
30 | protected $serializer; |
||
31 | |||
32 | /** |
||
33 | * @var string |
||
34 | */ |
||
35 | protected $prefix = ''; |
||
36 | |||
37 | /** |
||
38 | * @var bool |
||
39 | */ |
||
40 | protected $isReady = false; |
||
41 | |||
42 | /** |
||
43 | * @var bool |
||
44 | */ |
||
45 | protected $isActive = true; |
||
46 | |||
47 | /** |
||
48 | * @var bool |
||
49 | */ |
||
50 | protected $useCheckForDev; |
||
51 | |||
52 | /** |
||
53 | * @var bool |
||
54 | */ |
||
55 | protected $useCheckForAdminSession; |
||
56 | |||
57 | /** |
||
58 | * @var bool |
||
59 | */ |
||
60 | protected $useCheckForServerIpIsClientIp; |
||
61 | |||
62 | /** |
||
63 | * @var string |
||
64 | */ |
||
65 | protected $disableCacheGetParameter; |
||
66 | |||
67 | /** |
||
68 | * @var bool |
||
69 | */ |
||
70 | protected $isAdminSession; |
||
71 | |||
72 | /** |
||
73 | * @var array |
||
74 | */ |
||
75 | protected static $STATIC_CACHE = []; |
||
76 | |||
77 | /** |
||
78 | * @var array |
||
79 | */ |
||
80 | protected static $STATIC_CACHE_EXPIRE = []; |
||
81 | |||
82 | /** |
||
83 | * @var array |
||
84 | */ |
||
85 | protected static $STATIC_CACHE_COUNTER = []; |
||
86 | |||
87 | /** |
||
88 | * @var int |
||
89 | */ |
||
90 | protected $staticCacheHitCounter = 10; |
||
91 | |||
92 | /** |
||
93 | * __construct |
||
94 | * |
||
95 | * @param iAdapter|null $adapter |
||
96 | * @param iSerializer|null $serializer |
||
97 | * @param bool $checkForUsage <p>admin-session || server-ip == client-ip || check for |
||
98 | * dev</p> |
||
99 | * @param bool $cacheEnabled <p>false will disable the cache (use it e.g. for global |
||
100 | * settings)</p> |
||
101 | * @param bool|string $isAdminSession <p>set a admin-id, if the user is a admin (so we can |
||
102 | * disable cache for this user) |
||
103 | * @param bool $useCheckForAdminSession <p>use $isAdminSession flag or not</p> |
||
104 | * @param bool $useCheckForDev <p>use checkForDev() or not</p> |
||
105 | * @param bool $useCheckForServerIpIsClientIp <p>use check for server-ip == client-ip or not</p> |
||
106 | * @param string $disableCacheGetParameter <p>set the _GET parameter for disabling the cache, |
||
107 | * disable this check via empty string</p> |
||
108 | */ |
||
109 | 65 | public function __construct( |
|
173 | |||
174 | /** |
||
175 | * enable / disable the cache |
||
176 | * |
||
177 | * @param bool $isActive |
||
178 | */ |
||
179 | public function setActive(bool $isActive) |
||
183 | |||
184 | /** |
||
185 | * check if the current use is a admin || dev || server == client |
||
186 | * |
||
187 | * @return bool |
||
188 | */ |
||
189 | public function isCacheActiveForTheCurrentUser(): bool |
||
231 | |||
232 | /** |
||
233 | * returns the IP address of the client |
||
234 | * |
||
235 | * @param bool $trust_proxy_headers <p> |
||
236 | * Whether or not to trust the |
||
237 | * proxy headers HTTP_CLIENT_IP |
||
238 | * and HTTP_X_FORWARDED_FOR. ONLY |
||
239 | * use if your $_SERVER is behind a |
||
240 | * proxy that sets these values |
||
241 | * </p> |
||
242 | * |
||
243 | * @return string |
||
244 | */ |
||
245 | protected function getClientIp(bool $trust_proxy_headers = false): string |
||
263 | |||
264 | /** |
||
265 | * Check for local developer. |
||
266 | * |
||
267 | * @return bool |
||
268 | */ |
||
269 | protected function checkForDev(): bool |
||
298 | |||
299 | /** |
||
300 | * Set the default-prefix via "SERVER"-var + "SESSION"-language. |
||
301 | */ |
||
302 | 65 | protected function getTheDefaultPrefix(): string |
|
310 | |||
311 | /** |
||
312 | * Auto-connect to the available cache-system on the server. |
||
313 | * |
||
314 | * @return iAdapter |
||
315 | */ |
||
316 | protected function autoConnectToAvailableCacheSystem(): iAdapter |
||
457 | |||
458 | /** |
||
459 | * Set "isReady" state. |
||
460 | * |
||
461 | * @param bool $isReady |
||
462 | */ |
||
463 | 65 | protected function setCacheIsReady(bool $isReady) |
|
467 | |||
468 | /** |
||
469 | * Get the "isReady" state. |
||
470 | * |
||
471 | * @return bool |
||
472 | */ |
||
473 | 5 | public function getCacheIsReady(): bool |
|
477 | |||
478 | /** |
||
479 | * Get cached-item by key. |
||
480 | * |
||
481 | * @param string $key |
||
482 | * @param int $forceStaticCacheHitCounter |
||
483 | * |
||
484 | * @return mixed |
||
485 | */ |
||
486 | 31 | public function getItem(string $key, int $forceStaticCacheHitCounter = 0) |
|
541 | |||
542 | /** |
||
543 | * Calculate store-key (prefix + $rawKey). |
||
544 | * |
||
545 | * @param string $rawKey |
||
546 | * |
||
547 | * @return string |
||
548 | */ |
||
549 | 53 | protected function calculateStoreKey(string $rawKey): string |
|
559 | |||
560 | /** |
||
561 | * Clean store-key (required e.g. for the "File"-Adapter). |
||
562 | * |
||
563 | * @param string $str |
||
564 | * |
||
565 | * @return string |
||
566 | */ |
||
567 | 24 | protected function cleanStoreKey(string $str): string |
|
571 | |||
572 | /** |
||
573 | * Get the prefix. |
||
574 | * |
||
575 | * @return string |
||
576 | */ |
||
577 | 53 | public function getPrefix(): string |
|
581 | |||
582 | /** |
||
583 | * !!! Set the prefix. !!! |
||
584 | * |
||
585 | * WARNING: Do not use if you don't know what you do. Because this will overwrite the default prefix. |
||
586 | * |
||
587 | * @param string $prefix |
||
588 | */ |
||
589 | 65 | public function setPrefix(string $prefix) |
|
593 | |||
594 | /** |
||
595 | * Get the current value, when the static cache is used. |
||
596 | * |
||
597 | * @return int |
||
598 | */ |
||
599 | public function getStaticCacheHitCounter(): int |
||
603 | |||
604 | /** |
||
605 | * Set the static-hit-counter: Who often do we hit the cache, before we use static cache? |
||
606 | * |
||
607 | * @param int $staticCacheHitCounter |
||
608 | */ |
||
609 | public function setStaticCacheHitCounter(int $staticCacheHitCounter) |
||
613 | |||
614 | /** |
||
615 | * Set cache-item by key => value + date. |
||
616 | * |
||
617 | * @param string $key |
||
618 | * @param mixed $value |
||
619 | * @param \DateTime $date <p>If the date is in the past, we will remove the existing cache-item.</p> |
||
620 | * |
||
621 | * @throws InvalidArgumentException <p>If the $date is in the past.</p> |
||
622 | * |
||
623 | * @return bool |
||
624 | */ |
||
625 | 13 | public function setItemToDate(string $key, $value, \DateTime $date): bool |
|
635 | |||
636 | /** |
||
637 | * Set cache-item by key => value + ttl. |
||
638 | * |
||
639 | * @param string $key |
||
640 | * @param mixed $value |
||
641 | * @param \DateInterval|int|null $ttl |
||
642 | * |
||
643 | * @throws InvalidArgumentException |
||
644 | * |
||
645 | * @return bool |
||
646 | */ |
||
647 | 32 | public function setItem(string $key, $value, $ttl = 0): bool |
|
680 | |||
681 | /** |
||
682 | * Remove a cached-item. |
||
683 | * |
||
684 | * @param string $key |
||
685 | * |
||
686 | * @return bool |
||
687 | */ |
||
688 | 5 | public function removeItem(string $key): bool |
|
708 | |||
709 | /** |
||
710 | * Remove all cached-items. |
||
711 | * |
||
712 | * @return bool |
||
713 | */ |
||
714 | 3 | public function removeAll(): bool |
|
729 | |||
730 | /** |
||
731 | * Check if cached-item exists. |
||
732 | * |
||
733 | * @param string $key |
||
734 | * |
||
735 | * @return bool |
||
736 | */ |
||
737 | 11 | public function existsItem(string $key): bool |
|
752 | |||
753 | /** |
||
754 | * @param string $storeKey |
||
755 | * |
||
756 | * @return bool |
||
757 | */ |
||
758 | 36 | protected function checkForStaticCache(string $storeKey): bool |
|
768 | |||
769 | /** |
||
770 | * Get the current adapter class-name. |
||
771 | * |
||
772 | * @return string |
||
773 | */ |
||
774 | 3 | public function getUsedAdapterClassName(): string |
|
783 | |||
784 | /** |
||
785 | * Get the current serializer class-name. |
||
786 | * |
||
787 | * @return string |
||
788 | */ |
||
789 | 3 | public function getUsedSerializerClassName(): string |
|
798 | } |
||
799 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.