Complex classes like Connection 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 Connection, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
26 | class Connection implements ConnectionInterface |
||
27 | { |
||
28 | /** |
||
29 | * @var Factory |
||
30 | */ |
||
31 | private $factory; |
||
32 | |||
33 | /** |
||
34 | * @var string |
||
35 | */ |
||
36 | private $host; |
||
37 | |||
38 | /** |
||
39 | * @var int |
||
40 | */ |
||
41 | private $port; |
||
42 | |||
43 | /** |
||
44 | * @var bool |
||
45 | */ |
||
46 | private $secure; |
||
47 | |||
48 | /** |
||
49 | * @var Socket |
||
50 | */ |
||
51 | private $socket; |
||
52 | |||
53 | /** |
||
54 | * @var int |
||
55 | */ |
||
56 | private $timeout; |
||
57 | |||
58 | /** |
||
59 | * Constructor. |
||
60 | * |
||
61 | * @param string $host The hostname of the NNTP server. |
||
62 | * @param int $port The port of the NNTP server. |
||
63 | * @param bool $secure A bool indicating if a secure connection should be established. |
||
64 | * @param int $timeout The socket timeout in seconds. |
||
65 | * @param Factory $factory The socket client factory. |
||
66 | */ |
||
67 | 2 | public function __construct($host, $port, $secure = false, $timeout = 15, Factory $factory = null) |
|
75 | |||
76 | /** |
||
77 | * {@inheritdoc} |
||
78 | */ |
||
79 | 2 | public function connect() |
|
99 | |||
100 | /** |
||
101 | * {@inheritdoc} |
||
102 | */ |
||
103 | public function disconnect() |
||
111 | |||
112 | /** |
||
113 | * {@inheritdoc} |
||
114 | */ |
||
115 | public function sendCommand(CommandInterface $command) |
||
116 | { |
||
117 | $commandString = $command->execute(); |
||
118 | |||
119 | // NNTP/RFC977 only allows command up to 512 (-2 \r\n) chars. |
||
120 | if (!strlen($commandString) > 510) { |
||
121 | throw new InvalidArgumentException('Failed to write to socket: command exceeded 510 characters'); |
||
122 | } |
||
123 | |||
124 | if (!$this->socket->selectWrite() || strlen($commandString."\r\n") !== $this->socket->write($commandString."\r\n")) { |
||
125 | throw new RuntimeException('Failed to write to socket'); |
||
126 | } |
||
127 | |||
128 | $response = $this->getResponse(); |
||
129 | |||
130 | if ($command->isMultiLine() && ($response->getStatusCode() >= 200 && $response->getStatusCode() <= 399)) { |
||
131 | $response = $command->isCompressed() ? $this->getCompressedResponse($response) : $this->getMultiLineResponse($response); |
||
132 | } |
||
133 | |||
134 | if (in_array($response->getStatusCode(), [Response::COMMAND_UNKNOWN, Response::COMMAND_UNAVAILABLE])) { |
||
135 | throw new RuntimeException('Sent command is either unknown or unavailable on server'); |
||
136 | } |
||
137 | |||
138 | $expectedResponseCodes = $command->getExpectedResponseCodes(); |
||
139 | |||
140 | // Check if we received a response expected by the command. |
||
141 | if (!isset($expectedResponseCodes[$response->getStatusCode()])) { |
||
142 | throw new RuntimeException(sprintf( |
||
143 | 'Unexpected response received: [%d] %s', |
||
144 | $response->getStatusCode(), |
||
145 | $response->getMessage() |
||
146 | )); |
||
147 | } |
||
148 | |||
149 | $expectedResponseHandler = $expectedResponseCodes[$response->getStatusCode()]; |
||
150 | if (!is_callable([$command, $expectedResponseHandler])) { |
||
151 | throw new RuntimeException(sprintf('Response handler (%s) is not callable method on given command object', $expectedResponseHandler)); |
||
152 | } |
||
153 | |||
154 | $command->setResponse($response); |
||
155 | $command->$expectedResponseHandler($response); |
||
156 | |||
157 | return $command; |
||
158 | } |
||
159 | |||
160 | public function sendArticle(CommandInterface $command) |
||
191 | |||
192 | 1 | protected function getResponse() |
|
211 | |||
212 | public function getMultiLineResponse(Response $response) |
||
239 | |||
240 | public function getCompressedResponse(Response $response) |
||
276 | |||
277 | /** |
||
278 | * @param string $address |
||
279 | */ |
||
280 | 2 | protected function getSocketUrl($address) |
|
289 | } |
||
290 |