Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like ConnectionHandler 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 ConnectionHandler, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
40 | class ConnectionHandler implements ConnectionHandlerInterface |
||
41 | { |
||
42 | |||
43 | /** |
||
44 | * Hold's the server context instance |
||
45 | * |
||
46 | * @var \AppserverIo\Server\Interfaces\ServerContextInterface |
||
47 | */ |
||
48 | protected $serverContext; |
||
49 | |||
50 | /** |
||
51 | * Hold's the request's context instance |
||
52 | * |
||
53 | * @var \AppserverIo\Server\Interfaces\RequestContextInterface |
||
54 | */ |
||
55 | protected $requestContext; |
||
56 | |||
57 | /** |
||
58 | * Hold's an array of modules to use for connection handler |
||
59 | * |
||
60 | * @var array |
||
61 | */ |
||
62 | protected $modules; |
||
63 | |||
64 | /** |
||
65 | * Hold's the connection instance |
||
66 | * |
||
67 | * @var \AppserverIo\Psr\Socket\SocketInterface |
||
68 | */ |
||
69 | protected $connection; |
||
70 | |||
71 | /** |
||
72 | * Hold's the worker instance |
||
73 | * |
||
74 | * @var \AppserverIo\Server\Interfaces\WorkerInterface |
||
75 | */ |
||
76 | protected $worker; |
||
77 | |||
78 | /** |
||
79 | * Flag if a shutdown function was registered or not |
||
80 | * |
||
81 | * @var boolean |
||
82 | */ |
||
83 | protected $hasRegisteredShutdown = false; |
||
84 | |||
85 | /** |
||
86 | * Holds the stomp protocol handler. |
||
87 | * |
||
88 | * @var \AppserverIo\Stomp\Interfaces\ProtocolHandlerInterface |
||
89 | */ |
||
90 | protected $protocolHandler; |
||
91 | |||
92 | /** |
||
93 | * Holds the stomp frame. |
||
94 | * |
||
95 | * @var \AppserverIo\Stomp\Interfaces\FrameInterface |
||
96 | */ |
||
97 | protected $stompFrame; |
||
98 | |||
99 | /** |
||
100 | * Holds the stomp parser. |
||
101 | * |
||
102 | * @var \AppserverIo\Stomp\Interfaces\RequestParserInterface |
||
103 | */ |
||
104 | protected $stompParser; |
||
105 | |||
106 | /** |
||
107 | * The logger for the connection handler |
||
108 | * |
||
109 | * @var \Psr\Log\LoggerInterface |
||
110 | */ |
||
111 | protected $logger; |
||
112 | |||
113 | /** |
||
114 | * Holds the maximum command length in bytes. |
||
115 | * |
||
116 | * @var int |
||
117 | */ |
||
118 | protected $maxCommandLength = 20; |
||
119 | |||
120 | /** |
||
121 | * Holds the maximum count of header lines. |
||
122 | * |
||
123 | * @var int |
||
124 | */ |
||
125 | protected $maxHeaders = 1000; |
||
126 | |||
127 | /**. |
||
128 | * Holds the max string length of the header in bytes. |
||
129 | * |
||
130 | * @var int |
||
131 | */ |
||
132 | protected $maxHeaderLength = 102410; |
||
133 | |||
134 | /** |
||
135 | * Holds the max string length of the data in bytes. |
||
136 | * |
||
137 | * @var int |
||
138 | */ |
||
139 | protected $maxDataLength = 10241024100; |
||
140 | |||
141 | /** |
||
142 | * Holds must the connection closed. |
||
143 | * |
||
144 | * @var bool |
||
145 | */ |
||
146 | protected $closeConnection = false; |
||
147 | |||
148 | /** |
||
149 | * Holds the flag for developer mode. |
||
150 | * |
||
151 | * @var bool |
||
152 | */ |
||
153 | protected $developerMode = false; |
||
154 | |||
155 | /** |
||
156 | * Holds the configuration key for maxCommandLength. |
||
157 | * |
||
158 | * @var string |
||
159 | */ |
||
160 | const KEY_MAX_COMMAND_LENGTH = 'maxCommandLength'; |
||
161 | |||
162 | /** |
||
163 | * Holds the configuration key for maxHeaders. |
||
164 | * |
||
165 | * @var string |
||
166 | */ |
||
167 | const KEY_MAX_HEADERS = 'maxHeaders'; |
||
168 | |||
169 | /** |
||
170 | * Holds the configuration key for maxHeaderLength. |
||
171 | * |
||
172 | * @var string |
||
173 | */ |
||
174 | const KEY_MAX_HEADER_LENGTH = 'maxHeaderLength'; |
||
175 | |||
176 | /** |
||
177 | * Holds the configuration key for maxDataLength. |
||
178 | * |
||
179 | * @var string |
||
180 | */ |
||
181 | const KEY_MAX_DATA_LENGTH = 'maxDataLength'; |
||
182 | |||
183 | /** |
||
184 | * Holds the configuration key for developerMode. |
||
185 | * |
||
186 | * @var string |
||
187 | */ |
||
188 | const KEY_DEVELOPER_MODE = 'developerMode'; |
||
189 | |||
190 | /** |
||
191 | * Inits the connection handler by given context and params |
||
192 | * |
||
193 | * @param \AppserverIo\Server\Interfaces\ServerContextInterface $serverContext The server's context |
||
194 | * @param array $params The params for connection handler |
||
195 | * |
||
196 | * @return void |
||
197 | */ |
||
198 | public function init(ServerContextInterface $serverContext, array $params = null) |
||
217 | |||
218 | /** |
||
219 | * Init instances for the stompConnection handler |
||
220 | * |
||
221 | * @return void |
||
222 | */ |
||
223 | public function initInstances() |
||
231 | |||
232 | /** |
||
233 | * Injects all needed modules for connection handler to process |
||
234 | * |
||
235 | * @param array $modules An array of Modules |
||
236 | * |
||
237 | * @return void |
||
238 | */ |
||
239 | public function injectModules($modules) |
||
243 | |||
244 | /** |
||
245 | * Return's all needed modules as array for connection handler to process |
||
246 | * |
||
247 | * @return array An array of Modules |
||
248 | */ |
||
249 | public function getModules() |
||
253 | |||
254 | /** |
||
255 | * Return's a specific module instance by given name |
||
256 | * |
||
257 | * @param string $name The modules name to return an instance for |
||
258 | * |
||
259 | * @return \AppserverIo\WebServer\Interfaces\HttpModuleInterface | null |
||
260 | */ |
||
261 | public function getModule($name) |
||
269 | |||
270 | /** |
||
271 | * Return's the request's context instance |
||
272 | * |
||
273 | * @return \AppserverIo\Server\Interfaces\RequestContextInterface |
||
274 | * |
||
275 | * @codeCoverageIgnore |
||
276 | */ |
||
277 | public function getRequestContext() |
||
281 | |||
282 | /** |
||
283 | * Return's the server's configuration |
||
284 | * |
||
285 | * @return \AppserverIo\Server\Interfaces\ServerConfigurationInterface |
||
286 | * |
||
287 | * @codeCoverageIgnore |
||
288 | */ |
||
289 | public function getServerConfig() |
||
293 | |||
294 | /** |
||
295 | * Return's the server context instance |
||
296 | * |
||
297 | * @return \AppserverIo\Server\Interfaces\ServerContextInterface |
||
298 | * |
||
299 | * @codeCoverageIgnore |
||
300 | */ |
||
301 | public function getServerContext() |
||
305 | |||
306 | /** |
||
307 | * Handles the connection with the connected client in a proper way the given |
||
308 | * protocol type and version expects for example. |
||
309 | * |
||
310 | * @param \AppserverIo\Psr\Socket\SocketInterface $connection The connection to handle |
||
311 | * @param \AppserverIo\Server\Interfaces\WorkerInterface $worker The worker how started this handle |
||
312 | * |
||
313 | * @return boolean|null Weather it was responsible to handle the firstLine or not. |
||
314 | */ |
||
315 | public function handle(SocketInterface $connection, WorkerInterface $worker) |
||
390 | |||
391 | /** |
||
392 | * Inject the handler stomp handler to handle stomp request. |
||
393 | * |
||
394 | * @param ProtocolHandlerInterface $protocolHandler the protocol handler to inject. |
||
395 | * |
||
396 | * @return void |
||
397 | */ |
||
398 | public function injectProtocolHandler(ProtocolHandlerInterface $protocolHandler) |
||
402 | |||
403 | /** |
||
404 | * Logs with an arbitrary level. |
||
405 | * |
||
406 | * @param string $message The message to log |
||
407 | * @param Interfaces\FrameInterface $params The params to export |
||
408 | * @param string $level The level to log |
||
409 | * |
||
410 | * @return void |
||
411 | */ |
||
412 | protected function log($message, $params, $level = LogLevel::INFO) |
||
426 | |||
427 | /** |
||
428 | * Returns the protocol handler. |
||
429 | * |
||
430 | * @return \AppserverIo\Stomp\Interfaces\ProtocolHandlerInterface |
||
431 | * |
||
432 | * @codeCoverageIgnore |
||
433 | */ |
||
434 | public function getProtocolHandler() |
||
438 | |||
439 | /** |
||
440 | * Write a stomp frame |
||
441 | * |
||
442 | * @param \AppserverIo\Stomp\Frame $stompFrame The stomp frame to write |
||
443 | * @param \AppserverIo\Psr\Socket\SocketInterface $connection The connection to handle |
||
444 | * |
||
445 | * @return void |
||
446 | */ |
||
447 | public function writeFrame(Frame $stompFrame, SocketInterface $connection) |
||
453 | |||
454 | /** |
||
455 | * Registers the shutdown function in this context |
||
456 | * |
||
457 | * @return void |
||
458 | * |
||
459 | * @codeCoverageIgnore |
||
460 | */ |
||
461 | public function registerShutdown() |
||
469 | |||
470 | /** |
||
471 | * Does shutdown logic for worker if something breaks in process |
||
472 | * |
||
473 | * @return void |
||
474 | * |
||
475 | * @codeCoverageIgnore |
||
476 | */ |
||
477 | public function shutdown() |
||
495 | |||
496 | /** |
||
497 | * Return's the connection used to handle with |
||
498 | * |
||
499 | * @return \AppserverIo\Psr\Socket\SocketInterface |
||
500 | * |
||
501 | * @codeCoverageIgnore |
||
502 | */ |
||
503 | protected function getConnection() |
||
507 | |||
508 | /** |
||
509 | * Return's the worker instance which starte this worker thread |
||
510 | * |
||
511 | * @return \AppserverIo\Server\Interfaces\WorkerInterface |
||
512 | * |
||
513 | * @codeCoverageIgnore |
||
514 | */ |
||
515 | protected function getWorker() |
||
519 | |||
520 | /** |
||
521 | * Sets the config values for the connection handler. |
||
522 | * |
||
523 | * @param array $params config values to set. |
||
524 | * |
||
525 | * @return void |
||
526 | */ |
||
527 | public function setConfigValues($params = array()) |
||
554 | |||
555 | /** |
||
556 | * Read the headers from the connection |
||
557 | * |
||
558 | * @throws \AppserverIo\Stomp\Exception\ProtocolException |
||
559 | * |
||
560 | * @return void |
||
561 | */ |
||
562 | protected function handleHeader() |
||
592 | |||
593 | /** |
||
594 | * Read the stomp body from the connection |
||
595 | * |
||
596 | * @throws \AppserverIo\Stomp\Exception\ProtocolException |
||
597 | * |
||
598 | * @return void |
||
599 | */ |
||
600 | protected function handleBody() |
||
620 | } |
||
621 |
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.
Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.