Complex classes like Client 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 Client, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
33 | 1 | class Client implements IClient |
|
34 | { |
||
35 | /** |
||
36 | * Implement nette smart magic |
||
37 | */ |
||
38 | 1 | use Nette\SmartObject; |
|
39 | |||
40 | const VERSION = '0.1.0'; |
||
41 | |||
42 | const TYPE_ID_WELCOME = 0; |
||
43 | const TYPE_ID_PREFIX = 1; |
||
44 | const TYPE_ID_CALL = 2; |
||
45 | const TYPE_ID_CALL_RESULT = 3; |
||
46 | const TYPE_ID_CALL_ERROR = 4; |
||
47 | const TYPE_ID_SUBSCRIBE = 5; |
||
48 | const TYPE_ID_UNSUBSCRIBE = 6; |
||
49 | const TYPE_ID_PUBLISH = 7; |
||
50 | const TYPE_ID_EVENT = 8; |
||
51 | |||
52 | /** |
||
53 | * @var \Closure |
||
54 | */ |
||
55 | public $onConnect = []; |
||
56 | |||
57 | /** |
||
58 | * @var \Closure |
||
59 | */ |
||
60 | public $onOpen = []; |
||
61 | |||
62 | /** |
||
63 | * @var \Closure |
||
64 | */ |
||
65 | public $onEvent = []; |
||
66 | |||
67 | /** |
||
68 | * @var EventLoop\LoopInterface |
||
69 | */ |
||
70 | private $loop; |
||
71 | |||
72 | /** |
||
73 | * @var Configuration |
||
74 | */ |
||
75 | private $configuration; |
||
76 | |||
77 | /** |
||
78 | * @var Stream\DuplexResourceStream |
||
79 | */ |
||
80 | private $stream; |
||
81 | |||
82 | /** |
||
83 | * @var bool |
||
84 | */ |
||
85 | private $connected = FALSE; |
||
86 | |||
87 | /** |
||
88 | * @var callable[] |
||
89 | */ |
||
90 | private $sucessCallbacks = []; |
||
91 | |||
92 | /** |
||
93 | * @var callable[] |
||
94 | */ |
||
95 | private $errorCallbacks = []; |
||
96 | |||
97 | /** |
||
98 | * @param EventLoop\LoopInterface $loop |
||
99 | * @param Configuration $configuration |
||
100 | */ |
||
101 | function __construct(EventLoop\LoopInterface $loop, Configuration $configuration) |
||
106 | |||
107 | /** |
||
108 | * Disconnect on destruct |
||
109 | */ |
||
110 | function __destruct() |
||
114 | |||
115 | /** |
||
116 | * {@inheritdoc} |
||
117 | */ |
||
118 | public function setLoop(EventLoop\LoopInterface $loop) : void |
||
122 | |||
123 | /** |
||
124 | * {@inheritdoc} |
||
125 | */ |
||
126 | public function getLoop() : EventLoop\LoopInterface |
||
130 | |||
131 | /** |
||
132 | * {@inheritdoc} |
||
133 | */ |
||
134 | public function connect() : void |
||
159 | |||
160 | /** |
||
161 | * {@inheritdoc} |
||
162 | */ |
||
163 | public function disconnect() : void |
||
171 | |||
172 | /** |
||
173 | * {@inheritdoc} |
||
174 | */ |
||
175 | public function isConnected() : bool |
||
179 | |||
180 | /** |
||
181 | * {@inheritdoc} |
||
182 | */ |
||
183 | public function publish(string $topicUri, string $event, array $exclude = [], array $eligible = []) : void |
||
193 | |||
194 | /** |
||
195 | * {@inheritdoc} |
||
196 | */ |
||
197 | public function subscribe(string $topicUri) : void |
||
204 | |||
205 | /** |
||
206 | * {@inheritdoc} |
||
207 | */ |
||
208 | public function unsubscribe(string $topicUri) : void |
||
215 | |||
216 | /** |
||
217 | * {@inheritdoc} |
||
218 | */ |
||
219 | public function call(string $processUri, array $args, callable $successCallback = NULL, callable $errorCallback = NULL) : void |
||
235 | |||
236 | /** |
||
237 | * @param mixed $data |
||
238 | * @param array $header |
||
239 | * |
||
240 | * @return void |
||
241 | */ |
||
242 | private function receiveData($data, array $header) : void |
||
301 | |||
302 | /** |
||
303 | * @param array $data |
||
304 | * @param string $type |
||
305 | * @param bool $masked |
||
306 | * |
||
307 | * @return void |
||
308 | * |
||
309 | * @throws Utils\JsonException |
||
310 | */ |
||
311 | private function sendData(array $data, string $type = 'text', bool $masked = TRUE) : void |
||
321 | |||
322 | /** |
||
323 | * Parse received data |
||
324 | * |
||
325 | * @param array $response |
||
326 | * |
||
327 | * @return void |
||
328 | * |
||
329 | * @throws Utils\JsonException |
||
330 | */ |
||
331 | private function parseData(array $response) : void |
||
363 | |||
364 | /** |
||
365 | * Create header for web socket client |
||
366 | * |
||
367 | * @return string |
||
368 | */ |
||
369 | private function createHeader() : string |
||
390 | |||
391 | /** |
||
392 | * Parse raw incoming data |
||
393 | * |
||
394 | * @param string $header |
||
395 | * |
||
396 | * @return mixed[] |
||
397 | */ |
||
398 | private function parseChunk(string $header) : array |
||
433 | |||
434 | /** |
||
435 | * Generate token |
||
436 | * |
||
437 | * @param int $length |
||
438 | * |
||
439 | * @return string |
||
440 | */ |
||
441 | private function generateAlphaNumToken(int $length) : string |
||
456 | |||
457 | /** |
||
458 | * @param string $payload |
||
459 | * @param string $type |
||
460 | * @param bool $masked |
||
461 | * |
||
462 | * @return bool|string |
||
463 | */ |
||
464 | private function hybi10Encode(string $payload, string $type = 'text', bool $masked = TRUE) |
||
544 | |||
545 | /** |
||
546 | * @param $data |
||
547 | * |
||
548 | * @return string|NULL |
||
549 | */ |
||
550 | private function hybi10Decode($data) : ?string |
||
594 | } |
||
595 |
Adding explicit visibility (
private
,protected
, orpublic
) is generally recommend to communicate to other developers how, and from where this method is intended to be used.