Complex classes like Sms 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 Sms, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
15 | class Sms |
||
16 | { |
||
17 | /** |
||
18 | * Send task`s name. |
||
19 | * |
||
20 | * @var string |
||
21 | */ |
||
22 | const TASK = 'PhpSms'; |
||
23 | |||
24 | /** |
||
25 | * SMS agents(service providers), |
||
26 | * they are instances of class [Toplan\PhpSms\Agent]. |
||
27 | * |
||
28 | * @var array |
||
29 | */ |
||
30 | protected static $agents = []; |
||
31 | |||
32 | /** |
||
33 | * The enabled agents` name. |
||
34 | * |
||
35 | * @var array |
||
36 | */ |
||
37 | protected static $agentsName = []; |
||
38 | |||
39 | /** |
||
40 | * The enabled agents` config info. |
||
41 | * |
||
42 | * @var array |
||
43 | */ |
||
44 | protected static $agentsConfig = []; |
||
45 | |||
46 | /** |
||
47 | * Whether to use queue. |
||
48 | * |
||
49 | * @var bool |
||
50 | */ |
||
51 | protected static $enableQueue = false; |
||
52 | |||
53 | /** |
||
54 | * How to push to queue. |
||
55 | * |
||
56 | * @var \Closure |
||
57 | */ |
||
58 | protected static $howToUseQueue = null; |
||
59 | |||
60 | /** |
||
61 | * The enable hooks for balance task. |
||
62 | * |
||
63 | * @var array |
||
64 | */ |
||
65 | protected static $enableHooks = [ |
||
66 | 'beforeRun', |
||
67 | 'beforeDriverRun', |
||
68 | 'afterDriverRun', |
||
69 | 'afterRun', |
||
70 | ]; |
||
71 | |||
72 | /** |
||
73 | * An instance of class [SuperClosure\Serializer] |
||
74 | * |
||
75 | * @var Serializer |
||
76 | */ |
||
77 | protected static $serializer = null; |
||
78 | |||
79 | /** |
||
80 | * SMS(or voice verify) data container. |
||
81 | * |
||
82 | * @var array |
||
83 | */ |
||
84 | protected $smsData = [ |
||
85 | 'to' => null, |
||
86 | 'templates' => [], |
||
87 | 'content' => null, |
||
88 | 'templateData' => [], |
||
89 | 'voiceCode' => null, |
||
90 | ]; |
||
91 | |||
92 | /** |
||
93 | * The name of first agent. |
||
94 | * |
||
95 | * @var string|null |
||
96 | */ |
||
97 | protected $firstAgent = null; |
||
98 | |||
99 | /** |
||
100 | * Whether the current instance has already pushed to queue. |
||
101 | * |
||
102 | * @var bool |
||
103 | */ |
||
104 | protected $pushedToQueue = false; |
||
105 | |||
106 | /** |
||
107 | * Status container, |
||
108 | * store config data before serialize a instance(before enqueue). |
||
109 | * |
||
110 | * @var array |
||
111 | */ |
||
112 | protected $_status_before_enqueue_ = []; |
||
113 | |||
114 | /** |
||
115 | * Constructor |
||
116 | * |
||
117 | * @param bool $autoBoot |
||
118 | */ |
||
119 | 6 | public function __construct($autoBoot = true) |
|
125 | |||
126 | /** |
||
127 | * Boot balanced send task. |
||
128 | */ |
||
129 | 6 | public static function bootstrap() |
|
130 | { |
||
131 | 6 | $task = self::getTask(); |
|
132 | |||
133 | //注意这里判断Task实例有没有drivers,不能用empty,因为其不能检查语句, |
||
|
|||
134 | //而恰巧Task实例获取drivers是通过魔术方法获取的. |
||
135 | 6 | if (!count($task->drivers)) { |
|
136 | 3 | self::configuration(); |
|
137 | 3 | self::createDrivers($task); |
|
138 | 3 | } |
|
139 | 6 | } |
|
140 | |||
141 | /** |
||
142 | * Get or generate a balanced task instance for send SMS/voice verify. |
||
143 | * |
||
144 | * @return Task |
||
145 | */ |
||
146 | 15 | public static function getTask() |
|
154 | |||
155 | /** |
||
156 | * Configuration. |
||
157 | */ |
||
158 | 6 | protected static function configuration() |
|
168 | |||
169 | /** |
||
170 | * Try to read and set enable agents` name from config file. |
||
171 | * |
||
172 | * @param array $config |
||
173 | */ |
||
174 | 3 | protected static function initEnableAgents(array &$config) |
|
180 | |||
181 | /** |
||
182 | * Try to read and set enabled agents` config from config file. |
||
183 | * |
||
184 | * @param array $agents |
||
185 | * @param array $config |
||
186 | */ |
||
187 | 6 | protected static function initAgentsConfig(array $agents, array &$config) |
|
199 | |||
200 | /** |
||
201 | * validate configuration. |
||
202 | * |
||
203 | * @throws PhpSmsException |
||
204 | */ |
||
205 | 6 | protected static function validateConfig() |
|
211 | |||
212 | /** |
||
213 | * Create drivers of the balanced task. |
||
214 | * |
||
215 | * @param Task $task |
||
216 | */ |
||
217 | 18 | protected static function createDrivers(Task $task) |
|
251 | |||
252 | /** |
||
253 | * Parse the enabled agents` scheduling config data. |
||
254 | * 解析可用代理器的数组模式的调度配置 |
||
255 | * |
||
256 | * @param array $options |
||
257 | * |
||
258 | * @return array |
||
259 | */ |
||
260 | 3 | protected static function parseAgentArrayOptions(array $options) |
|
270 | |||
271 | /** |
||
272 | * Pull the character option data from the scheduling config. |
||
273 | * |
||
274 | * @param array $options |
||
275 | * @param string $name |
||
276 | * |
||
277 | * @return mixed |
||
278 | */ |
||
279 | 3 | protected static function pullAgentOptionByName(array &$options, $name) |
|
289 | |||
290 | /** |
||
291 | * Get agent config data by name. |
||
292 | * |
||
293 | * @param string $name |
||
294 | * |
||
295 | * @return array |
||
296 | */ |
||
297 | 3 | protected static function getAgentConfigData($name) |
|
301 | |||
302 | /** |
||
303 | * Get a sms agent instance by agent name, |
||
304 | * if null, will try to create a new agent instance. |
||
305 | * |
||
306 | * @param string $name |
||
307 | * @param array $configData |
||
308 | * |
||
309 | * @throws PhpSmsException |
||
310 | * |
||
311 | * @return mixed |
||
312 | */ |
||
313 | 21 | public static function getSmsAgent($name, array $configData) |
|
334 | |||
335 | /** |
||
336 | * Set enable agents. |
||
337 | * |
||
338 | * @param mixed $agentName |
||
339 | * @param mixed $options |
||
340 | */ |
||
341 | 6 | public static function enable($agentName, $options = null) |
|
355 | |||
356 | /** |
||
357 | * Set config info by agent name. |
||
358 | * |
||
359 | * @param array|string $agentName |
||
360 | * @param array $config |
||
361 | * |
||
362 | * @throws PhpSmsException |
||
363 | */ |
||
364 | 6 | public static function agents($agentName, array $config = []) |
|
377 | |||
378 | /** |
||
379 | * Get the enabled agents` name. |
||
380 | * |
||
381 | * @return array |
||
382 | */ |
||
383 | 12 | public static function getEnableAgents() |
|
387 | |||
388 | /** |
||
389 | * Get the enabled agents` config info. |
||
390 | * |
||
391 | * @return array |
||
392 | */ |
||
393 | 12 | public static function getAgentsConfig() |
|
397 | |||
398 | /** |
||
399 | * Tear down enable agents and prepare to create and start a new balance task, |
||
400 | * so before do it must destroy old task instance. |
||
401 | */ |
||
402 | 6 | public static function cleanEnableAgents() |
|
407 | |||
408 | /** |
||
409 | * Tear down agents config and prepare to create and start a new balance task, |
||
410 | * so before do it must destroy old task instance. |
||
411 | */ |
||
412 | 3 | public static function cleanAgentsConfig() |
|
417 | |||
418 | /** |
||
419 | * Create a sms instance which send SMS, |
||
420 | * and set SMS templates or content. |
||
421 | * |
||
422 | * @param mixed $agentName |
||
423 | * @param mixed $tempId |
||
424 | * |
||
425 | * @return Sms |
||
426 | */ |
||
427 | public static function make($agentName = null, $tempId = null) |
||
442 | |||
443 | /** |
||
444 | * Create a sms instance which send voice verify, |
||
445 | * and set verify code. |
||
446 | * |
||
447 | * @param string|int $code |
||
448 | * |
||
449 | * @return Sms |
||
450 | */ |
||
451 | 3 | public static function voice($code) |
|
458 | |||
459 | /** |
||
460 | * Set whether to use queue, and define how to use queue. |
||
461 | * |
||
462 | * @param mixed $enable |
||
463 | * @param mixed $handler |
||
464 | * |
||
465 | * @return bool |
||
466 | */ |
||
467 | 3 | public static function queue($enable = null, $handler = null) |
|
483 | |||
484 | /** |
||
485 | * Set the receiver`s mobile number. |
||
486 | * |
||
487 | * @param string $mobile |
||
488 | * |
||
489 | * @return $this |
||
490 | */ |
||
491 | 6 | public function to($mobile) |
|
497 | |||
498 | /** |
||
499 | * Set content for content SMS. |
||
500 | * |
||
501 | * @param string $content |
||
502 | * |
||
503 | * @return $this |
||
504 | */ |
||
505 | 3 | public function content($content) |
|
511 | |||
512 | /** |
||
513 | * Set template id for template SMS. |
||
514 | * |
||
515 | * @param mixed $agentName |
||
516 | * @param mixed $tempId |
||
517 | * |
||
518 | * @return $this |
||
519 | */ |
||
520 | 3 | public function template($agentName, $tempId = null) |
|
535 | |||
536 | /** |
||
537 | * Set template data for template SMS. |
||
538 | * |
||
539 | * @param array $data |
||
540 | * |
||
541 | * @return $this |
||
542 | */ |
||
543 | 3 | public function data(array $data) |
|
549 | |||
550 | /** |
||
551 | * Set the first agent by agent`s name. |
||
552 | * |
||
553 | * @param string $name |
||
554 | * |
||
555 | * @return $this |
||
556 | */ |
||
557 | 3 | public function agent($name) |
|
563 | |||
564 | /** |
||
565 | * Start send SMS/voice verify. |
||
566 | * |
||
567 | * If give a true parameter, will immediately start whatever whether to use queue. |
||
568 | * if you are already pushed sms instance to queue, you can recall the method `send()` in queue job without `true` parameter, |
||
569 | * so this mechanism in order to make you convenient use the method `send()` in queue system. |
||
570 | * |
||
571 | * @param bool $immediately |
||
572 | * |
||
573 | * @return mixed |
||
574 | */ |
||
575 | 18 | public function send($immediately = false) |
|
591 | |||
592 | /** |
||
593 | * Push to queue by custom method. |
||
594 | * |
||
595 | * @throws \Exception | PhpSmsException |
||
596 | * |
||
597 | * @return mixed |
||
598 | */ |
||
599 | 3 | public function push() |
|
614 | |||
615 | /** |
||
616 | * Get all the data of SMS/voice verify. |
||
617 | * |
||
618 | * @param null|string $name |
||
619 | * |
||
620 | * @return mixed |
||
621 | */ |
||
622 | 36 | public function getData($name = null) |
|
630 | |||
631 | /** |
||
632 | * Overload static method. |
||
633 | * |
||
634 | * @param string $name |
||
635 | * @param array $args |
||
636 | * |
||
637 | * @throws PhpSmsException |
||
638 | */ |
||
639 | 9 | public static function __callStatic($name, $args) |
|
640 | { |
||
641 | 9 | $name = $name === 'beforeSend' ? 'beforeRun' : $name; |
|
642 | 9 | $name = $name === 'afterSend' ? 'afterRun' : $name; |
|
643 | 9 | $name = $name === 'beforeAgentSend' ? 'beforeDriverRun' : $name; |
|
644 | 9 | $name = $name === 'afterAgentSend' ? 'afterDriverRun' : $name; |
|
645 | 9 | if (in_array($name, self::$enableHooks)) { |
|
646 | 9 | $handler = $args[0]; |
|
647 | 9 | $override = isset($args[1]) ? (bool) $args[1] : false; |
|
648 | 9 | if (is_callable($handler)) { |
|
649 | 9 | $task = self::getTask(); |
|
650 | 9 | $task->hook($name, $handler, $override); |
|
651 | 9 | } else { |
|
652 | throw new PhpSmsException("Please give method static $name() a callable parameter"); |
||
653 | } |
||
654 | 9 | } else { |
|
655 | throw new PhpSmsException("Do not find static method $name()"); |
||
656 | } |
||
657 | 9 | } |
|
658 | |||
659 | /** |
||
660 | * Overload method. |
||
661 | * |
||
662 | * @param string $name |
||
663 | * @param array $args |
||
664 | * |
||
665 | * @throws PhpSmsException |
||
666 | * @throws \Exception |
||
667 | */ |
||
668 | 3 | public function __call($name, $args) |
|
676 | |||
677 | /** |
||
678 | * Serialize magic method, |
||
679 | * store current sms instance status. |
||
680 | * |
||
681 | * @return array |
||
682 | */ |
||
683 | 3 | public function __sleep() |
|
695 | |||
696 | /** |
||
697 | * Unserialize magic method, |
||
698 | * note: the force bootstrap must before reinstall handlers! |
||
699 | */ |
||
700 | 3 | public function __wakeup() |
|
712 | |||
713 | /** |
||
714 | * Get a closure serializer. |
||
715 | * |
||
716 | * @return Serializer |
||
717 | */ |
||
718 | 3 | public static function getSerializer() |
|
726 | |||
727 | /** |
||
728 | * Serialize enabled agents. |
||
729 | * |
||
730 | * @return array |
||
731 | */ |
||
732 | 3 | protected static function serializeEnableAgents() |
|
744 | |||
745 | /** |
||
746 | * Unserialize enabled agents. |
||
747 | * |
||
748 | * @param array $serialized |
||
749 | * |
||
750 | * @return mixed |
||
751 | */ |
||
752 | 3 | protected static function unserializeEnableAgents(array $serialized) |
|
763 | |||
764 | /** |
||
765 | * Serialize character closure value of a array and replace origin value. |
||
766 | * |
||
767 | * @param array $options |
||
768 | * @param string $key |
||
769 | */ |
||
770 | 3 | protected static function serializeClosureAndReplace(array &$options, $key) |
|
777 | |||
778 | /** |
||
779 | * Unserialize character string of a array to closure and replace origin value. |
||
780 | * |
||
781 | * @param array $options |
||
782 | * @param string $key |
||
783 | */ |
||
784 | 3 | protected static function unserializeToClosureAndReplace(array &$options, $key) |
|
791 | |||
792 | /** |
||
793 | * Serialize these hooks` handlers: |
||
794 | * 'beforeRun','beforeDriverRun','afterDriverRun','afterRun'. |
||
795 | * |
||
796 | * @return array |
||
797 | */ |
||
798 | 3 | protected static function serializeHandlers() |
|
815 | |||
816 | /** |
||
817 | * Reinstall balance task hooks` handlers by serialized handlers. |
||
818 | * |
||
819 | * @param array $handlers |
||
820 | */ |
||
821 | 3 | protected static function reinstallHandlers(array $handlers) |
|
833 | } |
||
834 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.