Complex classes like Promocodes 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 Promocodes, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
11 | class Promocodes |
||
12 | { |
||
13 | /** |
||
14 | * Prefix for code generation |
||
15 | * |
||
16 | * @var string |
||
17 | */ |
||
18 | protected $prefix; |
||
19 | |||
20 | /** |
||
21 | * Suffix for code generation |
||
22 | * |
||
23 | * @var string |
||
24 | */ |
||
25 | protected $suffix; |
||
26 | |||
27 | /** |
||
28 | * Number of codes to be generated |
||
29 | * |
||
30 | * @var int |
||
31 | */ |
||
32 | protected $amount = 1; |
||
33 | |||
34 | /** |
||
35 | * Reward value which will be sticked to code |
||
36 | * |
||
37 | * @var null |
||
38 | */ |
||
39 | protected $reward = null; |
||
40 | |||
41 | /** |
||
42 | * Additional data to be returned with code |
||
43 | * |
||
44 | * @var array |
||
45 | */ |
||
46 | protected $data = []; |
||
47 | |||
48 | /** |
||
49 | * Number of days of code expiration |
||
50 | * |
||
51 | * @var null|int |
||
52 | */ |
||
53 | protected $expires_in = null; |
||
54 | |||
55 | /** |
||
56 | * Maximum number of available usage of code |
||
57 | * |
||
58 | * @var null|int |
||
59 | */ |
||
60 | protected $quantity = null; |
||
61 | |||
62 | /** |
||
63 | * If code should automatically invalidate after first use |
||
64 | * |
||
65 | * @var bool |
||
66 | */ |
||
67 | protected $disposable = false; |
||
68 | |||
69 | /** |
||
70 | * Generated codes will be saved here |
||
71 | * to be validated later. |
||
72 | * |
||
73 | * @var array |
||
74 | */ |
||
75 | private $codes = []; |
||
76 | |||
77 | /** |
||
78 | * Length of code will be calculated from asterisks you have |
||
79 | * set as mask in your config file. |
||
80 | * |
||
81 | * @var int |
||
82 | */ |
||
83 | private $length; |
||
84 | |||
85 | /** |
||
86 | * Promocodes constructor. |
||
87 | */ |
||
88 | public function __construct() |
||
101 | |||
102 | /** |
||
103 | * Save one-time use promocodes into database |
||
104 | * Successful insert returns generated promocodes |
||
105 | * Fail will return empty collection. |
||
106 | * |
||
107 | * @param int $amount |
||
108 | * @param float|null $reward |
||
109 | * @param array $data |
||
110 | * @param int|null $expires_in |
||
111 | * @param int|null $quantity |
||
112 | * |
||
113 | * @return \Illuminate\Support\Collection |
||
114 | */ |
||
115 | public function createDisposable( |
||
125 | |||
126 | /** |
||
127 | * Save promocodes into database |
||
128 | * Successful insert returns generated promocodes |
||
129 | * Fail will return empty collection. |
||
130 | * |
||
131 | * @param int $amount |
||
132 | * @param null $reward |
||
133 | * @param array $data |
||
134 | * @param int|null $expires_in |
||
135 | * @param bool $is_disposable |
||
136 | * @param int|null $quantity |
||
137 | * |
||
138 | * @return \Illuminate\Support\Collection |
||
139 | */ |
||
140 | public function create( |
||
172 | |||
173 | /** |
||
174 | * Generates promocodes as many as you wish. |
||
175 | * |
||
176 | * @param int $amount |
||
177 | * |
||
178 | * @return array |
||
179 | */ |
||
180 | public function output($amount = null) |
||
196 | |||
197 | /** |
||
198 | * Get number of codes to be generated |
||
199 | * |
||
200 | * @param null|int $request |
||
201 | * @return null|int |
||
202 | */ |
||
203 | public function getAmount($request) |
||
207 | |||
208 | /** |
||
209 | * Set how much code you want to be generated |
||
210 | * |
||
211 | * @param int $amount |
||
212 | * @return $this |
||
213 | */ |
||
214 | public function setAmount($amount) |
||
219 | |||
220 | /** |
||
221 | * Here will be generated single code using your parameters from config. |
||
222 | * |
||
223 | * @return string |
||
224 | */ |
||
225 | private function generate() |
||
251 | |||
252 | /** |
||
253 | * Your code will be validated to be unique for one request. |
||
254 | * |
||
255 | * @param $collection |
||
256 | * @param $new |
||
257 | * |
||
258 | * @return bool |
||
259 | */ |
||
260 | private function validate($collection, $new) |
||
264 | |||
265 | /** |
||
266 | * Get custom set reward value |
||
267 | * |
||
268 | * @param null|int $request |
||
269 | * @return null|int |
||
270 | */ |
||
271 | public function getReward($request) |
||
275 | |||
276 | /** |
||
277 | * Set custom reward value |
||
278 | * |
||
279 | * @param int $reward |
||
280 | * @return $this |
||
281 | */ |
||
282 | public function setReward($reward) |
||
287 | |||
288 | /** |
||
289 | * Get custom set data value |
||
290 | * |
||
291 | * @param null|array $data |
||
292 | * @return null|array |
||
293 | */ |
||
294 | public function getData($request) |
||
298 | |||
299 | /** |
||
300 | * Set custom data value |
||
301 | * |
||
302 | * @param array $data |
||
303 | * @return $this |
||
304 | */ |
||
305 | public function setData($data) |
||
310 | |||
311 | /** |
||
312 | * Get custom set expiration days value |
||
313 | * |
||
314 | * @param null|int $request |
||
315 | * @return null|int |
||
316 | */ |
||
317 | public function getExpiresIn($request) |
||
321 | |||
322 | /** |
||
323 | * Set custom expiration days value |
||
324 | * |
||
325 | * @param int $expires_in |
||
326 | * @return $this |
||
327 | */ |
||
328 | public function setExpiresIn($expires_in) |
||
333 | |||
334 | /** |
||
335 | * Get custom disposable value |
||
336 | * |
||
337 | * @param null|bool $request |
||
338 | * @return null|bool |
||
339 | */ |
||
340 | public function getDisposable($request) |
||
344 | |||
345 | /** |
||
346 | * Set custom disposable value |
||
347 | * |
||
348 | * @param bool $disposable |
||
349 | * @return $this |
||
350 | */ |
||
351 | public function setDisposable($disposable = true) |
||
356 | |||
357 | /** |
||
358 | * Get custom set quantity value |
||
359 | * |
||
360 | * @param null|int $request |
||
361 | * @return null|int |
||
362 | */ |
||
363 | public function getQuantity($request) |
||
367 | |||
368 | /** |
||
369 | * Set custom quantity value |
||
370 | * |
||
371 | * @param int $quantity |
||
372 | * @return $this |
||
373 | */ |
||
374 | public function setQuantity($quantity) |
||
379 | |||
380 | /** |
||
381 | * Set custom prefix for next generation |
||
382 | * |
||
383 | * @param string $prefix |
||
384 | * @return $this |
||
385 | */ |
||
386 | public function setPrefix($prefix) |
||
391 | |||
392 | /** |
||
393 | * Set custom suffix for next generation |
||
394 | * |
||
395 | * @param string $suffix |
||
396 | * @return $this |
||
397 | */ |
||
398 | public function setSuffix($suffix) |
||
403 | |||
404 | /** |
||
405 | * Reedem promocode to user that it's used from now. |
||
406 | * |
||
407 | * @param string $code |
||
408 | * |
||
409 | * @return bool|Promocode |
||
410 | * @throws AlreadyUsedException |
||
411 | * @throws UnauthenticatedException |
||
412 | */ |
||
413 | public function redeem($code) |
||
417 | |||
418 | /** |
||
419 | * Apply promocode to user that it's used from now. |
||
420 | * |
||
421 | * @param string $code |
||
422 | * |
||
423 | * @return bool|Promocode |
||
424 | * @throws AlreadyUsedException |
||
425 | * @throws UnauthenticatedException |
||
426 | */ |
||
427 | public function apply($code) |
||
453 | |||
454 | /** |
||
455 | * Check promocode in database if it is valid. |
||
456 | * |
||
457 | * @param string $code |
||
458 | * |
||
459 | * @return bool|Promocode |
||
460 | */ |
||
461 | public function check($code) |
||
471 | |||
472 | /** |
||
473 | * Check if user is trying to apply code again. |
||
474 | * |
||
475 | * @param Promocode $promocode |
||
476 | * |
||
477 | * @return bool |
||
478 | */ |
||
479 | public function isSecondUsageAttempt(Promocode $promocode) |
||
480 | { |
||
481 | return $promocode->isDisposable() && $promocode->users()->wherePivot(config('promocodes.related_pivot_key', 'user_id'), |
||
482 | auth()->id())->exists(); |
||
483 | } |
||
484 | |||
485 | /** |
||
486 | * Expire code as it won't be usable anymore. |
||
487 | * |
||
488 | * @param string $code |
||
489 | * @return bool |
||
490 | * @throws InvalidPromocodeException |
||
491 | */ |
||
492 | public function disable($code) |
||
505 | |||
506 | /** |
||
507 | * Clear all expired and used promotion codes |
||
508 | * that can not be used anymore. |
||
509 | * |
||
510 | * @return void |
||
511 | */ |
||
512 | public function clearRedundant() |
||
521 | |||
522 | /** |
||
523 | * Get the list of valid promocodes |
||
524 | * |
||
525 | * @return Promocode[]|\Illuminate\Database\Eloquent\Collection |
||
526 | */ |
||
527 | public function all() |
||
533 | } |
||
534 |
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.