Complex classes like AbstractRand 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 AbstractRand, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
11 | abstract class AbstractRand |
||
12 | { |
||
13 | /** |
||
14 | * Maximum possible value of randomInt() generator in derived class. |
||
15 | * Must be overridden to correct value if different from default uint32 |
||
16 | */ |
||
17 | const INT_MAX = 0xFFFFFFFF; |
||
18 | |||
19 | /** |
||
20 | * Helper constants with common character lists for randomString() method |
||
21 | */ |
||
22 | const CL_ALNUM = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; |
||
23 | const CL_NUM = '0123456789'; |
||
24 | const CL_ALUC = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; |
||
25 | const CL_ALLC = 'abcdefghijklmnopqrstuvwxyz'; |
||
26 | const CL_HEXUC = '0123456789ABCDEF'; |
||
27 | const CL_HEXLC = '0123456789abcdef'; |
||
28 | |||
29 | /** |
||
30 | * @var string User specified seed used to initialize a PRNG |
||
31 | */ |
||
32 | protected $seed; |
||
33 | /** |
||
34 | * @var string 128bit binary md5 hash from seed. |
||
35 | * Should be used as data source for PRNG initialization |
||
36 | */ |
||
37 | protected $hashedSeed; |
||
38 | /** |
||
39 | * @var float Helper var = 1/INT_MAX |
||
40 | */ |
||
41 | protected $intMaxDiv; |
||
42 | |||
43 | /** |
||
44 | * @var mixed Internal generator's state. |
||
45 | * Derived class must use it for storing current state of prng. |
||
46 | * Can be saved and sets back to "replay" random sequences |
||
47 | */ |
||
48 | protected $state; |
||
49 | |||
50 | /** |
||
51 | * @var array State stack, used by pushState() and popState() methods |
||
52 | */ |
||
53 | protected $stateStack = []; |
||
54 | |||
55 | /** |
||
56 | * @var GaussianSampler Normal distributed random numbers generator |
||
57 | */ |
||
58 | protected $gaussianSampler; |
||
59 | |||
60 | /** |
||
61 | * Initializes random generator |
||
62 | * Must be implemented by derived class |
||
63 | */ |
||
64 | abstract protected function init(); |
||
65 | |||
66 | /** |
||
67 | * Returns random unsigned integer. Int size depends on generator's algorithm. |
||
68 | * Must be implemented by derived class |
||
69 | * |
||
70 | * @return int Random number |
||
71 | */ |
||
72 | abstract public function randomInt(); |
||
73 | |||
74 | /** |
||
75 | * Class constructor. Initializes generator from specified $seed string |
||
76 | * |
||
77 | * @param string $seed Seed to initialize generator's state. Defaults to null (auto) |
||
78 | */ |
||
79 | public function __construct($seed = null) |
||
84 | |||
85 | /** |
||
86 | * Sets new seed and initializes generator |
||
87 | * |
||
88 | * @param string|int $seed New seed for PRNG. If null is given, creates random seed from mt_rand |
||
89 | */ |
||
90 | public function setSeed($seed = null) |
||
96 | |||
97 | /** |
||
98 | * Returns seed used to initialize PRNG |
||
99 | * |
||
100 | * @return string Seed |
||
101 | */ |
||
102 | public function getSeed() |
||
106 | |||
107 | /** |
||
108 | * Sets PRNG state, previously saved by getState() function |
||
109 | * |
||
110 | * @param array $state State array with seed and internal generator's state |
||
111 | * @throws RandException |
||
112 | */ |
||
113 | public function setState(array $state) |
||
125 | |||
126 | /** |
||
127 | * Returns array with class name, seed and current internal state |
||
128 | * This state can be used to save generator's state in custom position and "replay" rnd sequences |
||
129 | * |
||
130 | * @return array Information needed to restore generator to known state |
||
131 | */ |
||
132 | public function getState() |
||
140 | |||
141 | /** |
||
142 | * Pushes current internal generator's state onto stack. |
||
143 | */ |
||
144 | public function pushState() |
||
148 | |||
149 | /** |
||
150 | * Restores last pushed internal generator's state from stack |
||
151 | * |
||
152 | * @throws RandException if stack is empty |
||
153 | */ |
||
154 | public function popState() |
||
162 | |||
163 | /** |
||
164 | * Resets generator to initial state |
||
165 | */ |
||
166 | public function reset() |
||
170 | |||
171 | /** |
||
172 | * @param float $mean |
||
173 | * @param float $sigma |
||
174 | * @return float Normally distributed random number |
||
175 | */ |
||
176 | public function gaussianRandom($mean = 0.0, $sigma = 1.0) |
||
185 | |||
186 | /** |
||
187 | * Returns uniformly distributed random number within given range. |
||
188 | * In case of incorrect range RandException will be thrown |
||
189 | * |
||
190 | * @param int $min Range min. Defaults to 0. |
||
191 | * @param int $max Range max. Defaults to INT_MAX |
||
192 | * @return int Random number in specified range inclusive |
||
193 | * @throws RandException |
||
194 | */ |
||
195 | public function random($min = 0, $max = null) |
||
206 | |||
207 | /** |
||
208 | * Returns unsigned float |
||
209 | * |
||
210 | * @return float Random float value in range 0 <= num <= 1 |
||
211 | */ |
||
212 | public function randomFloat() |
||
216 | |||
217 | /** |
||
218 | * Returns true or false |
||
219 | * |
||
220 | * @return bool Random boolean value |
||
221 | */ |
||
222 | public function randomBool() |
||
226 | |||
227 | /** |
||
228 | * Returns random binary data with given length. |
||
229 | * May be optimised by derived class depending on generator algorithm used |
||
230 | * |
||
231 | * @param int $length Length of data to generate |
||
232 | * @return string Random binary data |
||
233 | * @throws RandException |
||
234 | */ |
||
235 | public function randomData($length) |
||
252 | |||
253 | /** |
||
254 | * Generate random string with given length from specified character list. |
||
255 | * Supports multi-byte characters when $mb flag is set |
||
256 | * |
||
257 | * @param int $length Length of string to generate |
||
258 | * @param string $charList List of characters to create string from |
||
259 | * @param bool $mb Whether to interpret $charList as multibyte string. Defaults to false |
||
260 | * @return string Random string |
||
261 | */ |
||
262 | public function randomString($length, $charList = self::CL_ALNUM, $mb = false) |
||
277 | |||
278 | /** |
||
279 | * Returns random key from given array |
||
280 | * |
||
281 | * @param array $array Array to get random key from |
||
282 | * @return mixed Random array's key |
||
283 | * @throws RandException |
||
284 | */ |
||
285 | public function arrayRand(array $array) |
||
295 | |||
296 | /** |
||
297 | * Returns random element from given array |
||
298 | * |
||
299 | * @param array $array Array to get random element from |
||
300 | * @return mixed Random array's element |
||
301 | */ |
||
302 | public function arrayRandValue(array $array) |
||
306 | |||
307 | /** |
||
308 | * Shuffles given array by reference like php shuffle() function |
||
309 | * This function assigns new keys to the elements in array. |
||
310 | * |
||
311 | * @param array $array Array for shuffling |
||
312 | */ |
||
313 | public function arrayShuffle(array &$array) |
||
323 | |||
324 | /** |
||
325 | * Shuffles given array by reference like php shuffle() function |
||
326 | * Preserves key => value pairs |
||
327 | * |
||
328 | * @param array $array Reference to array for shuffling |
||
329 | */ |
||
330 | public function arrayShuffleAssoc(array &$array) |
||
346 | |||
347 | /** |
||
348 | * Returns random key from input array by its weight |
||
349 | * Array must be specified in [key => weight, ...] form |
||
350 | * |
||
351 | * @param array $array Input array with with key => weight elements |
||
352 | * @return mixed Random key |
||
353 | * @throws RandException |
||
354 | */ |
||
355 | public function arrayWeightRand(array $array) |
||
376 | |||
377 | /** |
||
378 | * Shuffles input array by element's weights. |
||
379 | * Array must be specified in [key => weight, ...] form |
||
380 | * |
||
381 | * @param array $array Array for shuffling |
||
382 | */ |
||
383 | public function arrayWeightShuffle(array &$array) |
||
395 | |||
396 | /** |
||
397 | * Simple array shuffle helper function |
||
398 | * |
||
399 | * @param array $array |
||
400 | */ |
||
401 | private function shuffle(array &$array) |
||
410 | } |
||
411 |
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.