Complex classes like SmallFilesQueueTransport 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 SmallFilesQueueTransport, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
7 | class SmallFilesQueueTransport extends AbstractQueueTransport { |
||
8 | const SINGLE_FILE_DB_VERSION = 1; |
||
9 | |||
10 | protected $_message_folder; |
||
11 | protected $_queue_name; |
||
12 | protected $_message_folder_subfolder_count = Queue::DefaultMessageFolderSubfolderCount; |
||
13 | protected $_key_to_file = []; |
||
14 | protected $_is_inotify_enabled; |
||
15 | protected $_chunk_file_postfix = ''; |
||
16 | |||
17 | /** |
||
18 | * @var iMessage[] |
||
19 | */ |
||
20 | protected $_last_consumed_messages = []; |
||
21 | /** |
||
22 | * @var integer[] В keys список файлов, которые были прочитаны |
||
23 | */ |
||
24 | protected $_consumed_filenames = []; |
||
25 | |||
26 | /** |
||
27 | * @param SmallFilesQueueConstructionSettings|object $settings |
||
28 | * |
||
29 | * @throws QueueException |
||
30 | */ |
||
31 | 68 | function __construct($settings) { |
|
1 ignored issue
–
show
|
|||
32 | 68 | if (!isset($settings->message_folder)) { |
|
33 | 4 | throw new QueueException('message_folder has not been set'); |
|
34 | } |
||
35 | 64 | if (!isset($settings->name)) { |
|
36 | 4 | throw new QueueException('name has not been set'); |
|
37 | } |
||
38 | 60 | $this->_message_folder = $settings->message_folder; |
|
39 | 60 | $this->_queue_name = $settings->name; |
|
40 | 60 | if (isset($settings->message_folder_subfolder_count)) { |
|
41 | $this->_message_folder_subfolder_count = $settings->message_folder_subfolder_count; |
||
42 | } |
||
43 | 60 | if (isset($settings->is_inotify_enabled)) { |
|
44 | $this->_is_inotify_enabled = $settings->is_inotify_enabled; |
||
45 | } else { |
||
46 | 60 | $this->_is_inotify_enabled = function_exists('inotify_init'); |
|
47 | } |
||
48 | 60 | $this->_chunk_file_postfix = '_'.static::generate_rnd_postfix(); |
|
49 | 60 | } |
|
50 | |||
51 | /** |
||
52 | * @param boolean $mode |
||
53 | * |
||
54 | * @hint Ничего не делаем, у этого транспорта нет эксклюзивного режима |
||
55 | * @codeCoverageIgnore |
||
56 | */ |
||
57 | function set_exclusive_mode($mode) { } |
||
58 | |||
59 | /** |
||
60 | * @return string |
||
61 | */ |
||
62 | 692 | function get_queue_name() { |
|
65 | |||
66 | 620 | function save() { |
|
98 | |||
99 | /** |
||
100 | * @param double|integer $wait_time |
||
101 | * |
||
102 | * @return iMessage|object|null |
||
103 | * @throws QueueException |
||
104 | */ |
||
105 | 696 | function consume_next_message($wait_time = -1) { |
|
122 | |||
123 | 8 | function clear_consumed_keys() { |
|
128 | |||
129 | 736 | function __clone() { |
|
135 | |||
136 | /** |
||
137 | * @param double|integer $wait_time |
||
138 | * |
||
139 | * @return iMessage|object|null |
||
140 | */ |
||
141 | 696 | protected function consume_next_message_without_inotify($wait_time = -1) { |
|
158 | |||
159 | /** |
||
160 | * @param string $folder |
||
161 | * |
||
162 | * @return iMessage|object|null |
||
163 | */ |
||
164 | 680 | protected function consume_next_message_without_inotify_folder($folder) { |
|
181 | |||
182 | |||
183 | /** |
||
184 | * Забираем новые event'ы из файла. Файл должен быть уже существующим, читабельным |
||
185 | * |
||
186 | * Проверка на присутствие в индексе осуществляется в этом файле |
||
187 | * |
||
188 | * @param string $filename |
||
189 | * |
||
190 | * @return iMessage|object|null |
||
191 | */ |
||
192 | 680 | protected function consume_next_message_from_file($filename) { |
|
193 | 680 | if (isset($this->_consumed_filenames[$filename])) { |
|
194 | 660 | return null; |
|
195 | } |
||
196 | |||
197 | 680 | $fi = fopen($filename, 'r'); |
|
198 | 680 | $locked = flock($fi, LOCK_EX | LOCK_NB); |
|
199 | 680 | if (!$locked) { |
|
200 | 4 | fclose($fi); |
|
201 | |||
202 | 4 | return null; |
|
203 | } |
||
204 | |||
205 | 680 | $buf = file_get_contents($filename); |
|
206 | /** |
||
207 | * @var SmallFilesQueueSingleFile $file_data |
||
208 | */ |
||
209 | 680 | $file_data = @unserialize($buf); |
|
210 | 680 | if (!is_object($file_data)) { |
|
211 | // File does not contain Single Queue object |
||
212 | 3 | flock($fi, LOCK_UN); |
|
213 | 3 | fclose($fi); |
|
214 | |||
215 | 3 | return null; |
|
216 | } |
||
217 | 680 | if ($file_data->queue_name != $this->get_queue_name()) { |
|
218 | 8 | flock($fi, LOCK_UN); |
|
219 | 8 | fclose($fi); |
|
220 | |||
221 | 8 | return null; |
|
222 | } |
||
223 | 680 | if ($file_data->version != self::SINGLE_FILE_DB_VERSION) { |
|
224 | flock($fi, LOCK_UN); |
||
225 | fclose($fi); |
||
226 | |||
227 | return null; |
||
228 | } |
||
229 | |||
230 | 680 | $this->_last_consumed_messages = []; |
|
231 | 680 | foreach ($file_data->queue as $message) { |
|
232 | 680 | $key = self::get_real_key_for_message($message); |
|
233 | 680 | if (isset($this->_consumed_keys[$key])) { |
|
234 | 8 | continue; |
|
235 | } |
||
236 | |||
237 | 680 | $message->time_consumed = microtime(true); |
|
238 | 680 | $message->queue = $this; |
|
239 | 680 | $this->_key_to_file[$key] = $filename; |
|
240 | 680 | $this->_last_consumed_messages[] = $message; |
|
241 | 680 | $this->_consumed_keys[$key] = 1; |
|
242 | 170 | } |
|
243 | 680 | flock($fi, LOCK_UN); |
|
244 | 680 | fclose($fi); |
|
245 | 680 | $this->_consumed_filenames[$filename] = 1; |
|
246 | |||
247 | 680 | return !empty($this->_last_consumed_messages) ? array_shift($this->_last_consumed_messages) : null; |
|
248 | } |
||
249 | |||
250 | /** |
||
251 | * @param iMessage[]|object[] $messages |
||
252 | */ |
||
253 | 312 | protected function copy_key_to_file_from_messages(array $messages) { |
|
262 | |||
263 | /** |
||
264 | * @param iMessage[]|object[] $messages |
||
265 | * |
||
266 | * @return array[] |
||
267 | */ |
||
268 | 312 | protected function get_filenames_from_messages(array $messages) { |
|
288 | |||
289 | /** |
||
290 | * Удалить сообщения и сразу же записать это в БД |
||
291 | * |
||
292 | * @param iMessage[]|object[] $messages |
||
293 | * |
||
294 | * @return string[]|integer[] |
||
295 | * @throws QueueException |
||
296 | */ |
||
297 | 312 | function delete_messages(array $messages) { |
|
406 | |||
407 | /** |
||
408 | * Обновляем сообщение и сразу же сохраняем всё |
||
409 | * |
||
410 | * Эта функция не рейзит ошибку, если сообщение не найдено |
||
411 | * |
||
412 | * @param iMessage|object $message |
||
413 | * @param string|null $key форсированно задаём ключ сообщения |
||
414 | * |
||
415 | * @return boolean |
||
416 | * @throws QueueException |
||
417 | */ |
||
418 | 320 | function update_message($message, $key = null) { |
|
485 | |||
486 | /** |
||
487 | * Поддерживает ли очередь сортировку event'ов при вставке |
||
488 | * |
||
489 | * @return boolean |
||
490 | */ |
||
491 | 4 | static function is_support_sorted_events() { |
|
494 | |||
495 | /* |
||
496 | * @param double|integer $wait_time |
||
497 | * |
||
498 | * @return iMessage|object|null |
||
499 | * |
||
500 | * @throws QueueException |
||
501 | * @codeCoverageIgnore |
||
502 | / |
||
503 | protected function consume_next_message_with_inotify($wait_time = -1) { |
||
504 | $start = microtime(true); |
||
505 | // @todo написать |
||
506 | throw new QueueException('Не готово'); |
||
507 | } |
||
508 | */ |
||
509 | |||
510 | /* |
||
511 | * @codeCoverageIgnore |
||
512 | / |
||
513 | function test_inotify() { |
||
514 | // @todo этого тут быть не должно |
||
515 | $a = inotify_init(); |
||
516 | } |
||
517 | */ |
||
518 | |||
519 | /** |
||
520 | * @param SmallFilesQueueTransport $queue |
||
521 | * |
||
522 | * @return boolean |
||
523 | */ |
||
524 | 340 | function is_equal_to($queue) { |
|
535 | } |
||
536 | |||
537 | ?> |
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.