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 FileManager 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 FileManager, and based on these observations, apply Extract Interface, too.
1 | <?php namespace FreedomCore\TrinityCore\Support\DB2Reader; |
||
13 | class FileManager |
||
14 | { |
||
15 | |||
16 | /** |
||
17 | * Build Number |
||
18 | * @var null|int |
||
19 | */ |
||
20 | protected $build = null; |
||
21 | |||
22 | /** |
||
23 | * Filesystem Instance |
||
24 | * @var Filesystem|null |
||
25 | */ |
||
26 | protected $fileSystem = null; |
||
27 | |||
28 | /** |
||
29 | * File handle resource instance |
||
30 | * @var null|resource |
||
31 | */ |
||
32 | protected $fileHandle = null; |
||
33 | |||
34 | /** |
||
35 | * Currently opened file |
||
36 | * @var null|string |
||
37 | */ |
||
38 | protected $fileName = null; |
||
39 | |||
40 | /** |
||
41 | * Processor Instance |
||
42 | * @var WDC1|WDB5|WDB2|BaseFormat|null |
||
43 | */ |
||
44 | protected $processor = null; |
||
45 | |||
46 | /** |
||
47 | * Whether the structure for the file exists or not |
||
48 | * @var bool |
||
49 | */ |
||
50 | protected $structureExists = false; |
||
51 | |||
52 | /** |
||
53 | * File structure |
||
54 | * @var null|array |
||
55 | */ |
||
56 | protected $fileStructure = null; |
||
57 | |||
58 | /** |
||
59 | * Whether all required items have been loaded |
||
60 | * @var bool |
||
61 | */ |
||
62 | protected $loaded = false; |
||
63 | |||
64 | /** |
||
65 | * Structure for data folder |
||
66 | * @var array |
||
67 | */ |
||
68 | protected $dataFolderStructure = []; |
||
69 | |||
70 | /** |
||
71 | * List of available DBC languages |
||
72 | * @var array |
||
73 | */ |
||
74 | protected $availableLanguages = []; |
||
75 | |||
76 | /** |
||
77 | * Available DBC/DB2 files |
||
78 | * @var array |
||
79 | */ |
||
80 | protected $availableFiles = []; |
||
81 | |||
82 | /** |
||
83 | * Data acquired from initial processing |
||
84 | * @var array |
||
85 | */ |
||
86 | protected $initialProcessing = []; |
||
87 | |||
88 | /** |
||
89 | * FileManager constructor. |
||
90 | * @param Filesystem $fs |
||
91 | * @param int $build |
||
92 | */ |
||
93 | public function __construct(Filesystem $fs, int $build) |
||
98 | |||
99 | /** |
||
100 | * FileManager destructor. |
||
101 | */ |
||
102 | public function __destruct() |
||
108 | |||
109 | /** |
||
110 | * Get file system instance |
||
111 | * @return Filesystem |
||
112 | */ |
||
113 | public function getFileSystem() : Filesystem |
||
117 | |||
118 | /** |
||
119 | * Set file system instance |
||
120 | * @param Filesystem $fs |
||
121 | */ |
||
122 | public function setFileSystem(Filesystem $fs) |
||
126 | |||
127 | /** |
||
128 | * Get file handle instance |
||
129 | * @return null|resource |
||
130 | */ |
||
131 | public function getFileHandle() |
||
135 | |||
136 | /** |
||
137 | * Set file name |
||
138 | * @param string $fileName |
||
139 | */ |
||
140 | public function setFileName(string $fileName) |
||
144 | |||
145 | /** |
||
146 | * Get file name |
||
147 | * @return string |
||
148 | */ |
||
149 | public function getFileName() : string |
||
153 | |||
154 | /** |
||
155 | * Set file handle instance |
||
156 | * @param $fileHandle |
||
157 | */ |
||
158 | public function setFileHandle($fileHandle) |
||
162 | |||
163 | /** |
||
164 | * Check if file structure exists |
||
165 | * @return bool |
||
166 | */ |
||
167 | public function structureExists() : bool |
||
171 | |||
172 | /** |
||
173 | * Get File Structure |
||
174 | * @return null|array |
||
175 | */ |
||
176 | public function getStructure() : array |
||
180 | |||
181 | /** |
||
182 | * Load structure of the data folder |
||
183 | * @return array |
||
184 | */ |
||
185 | public function loadDataDirectory() : array |
||
199 | |||
200 | /** |
||
201 | * Load information about all available DBC languages |
||
202 | * @return array |
||
203 | */ |
||
204 | public function loadAvailableLanguages() : array |
||
222 | |||
223 | /** |
||
224 | * Load all available files |
||
225 | * @param string $selectedLanguage |
||
226 | * @return array |
||
227 | */ |
||
228 | public function loadAvailableFiles(string $selectedLanguage) : array |
||
243 | |||
244 | /** |
||
245 | * Load everything required for operation |
||
246 | * @param string $selectedLanguage |
||
247 | */ |
||
248 | public function loadEverything(string $selectedLanguage) |
||
255 | |||
256 | /** |
||
257 | * Check if we are ready to perform other tasks |
||
258 | * @return bool |
||
259 | */ |
||
260 | public function isReady() : bool |
||
264 | |||
265 | /** |
||
266 | * Get available languages |
||
267 | * @return array |
||
268 | */ |
||
269 | public function getLanguages() : array |
||
273 | |||
274 | /** |
||
275 | * Get available languages as codes |
||
276 | * @return array |
||
277 | */ |
||
278 | public function getLanguageCodes() : array |
||
284 | |||
285 | /** |
||
286 | * Get data folder structure |
||
287 | * @return array |
||
288 | */ |
||
289 | public function getDataFolderStructure() : array |
||
293 | |||
294 | /** |
||
295 | * Get processor instance |
||
296 | * @return WDB5|WDB2|BaseFormat|null |
||
297 | */ |
||
298 | public function getProcessor() |
||
302 | |||
303 | /** |
||
304 | * Check if requested file actually exists |
||
305 | * @param string $fileName |
||
306 | * @return bool |
||
307 | */ |
||
308 | public function isFileAvailable(string $fileName) : bool |
||
313 | |||
314 | /** |
||
315 | * Open requested file |
||
316 | * @param string $fileName |
||
317 | * @param array $arguments |
||
318 | * @throws \Exception |
||
319 | */ |
||
320 | public function openFile(string $fileName, array $arguments = []) |
||
329 | |||
330 | /** |
||
331 | * Format file name string |
||
332 | * @param string $fileName |
||
333 | * @return string |
||
334 | */ |
||
335 | public function formatFileName(string $fileName) : string |
||
342 | |||
343 | /** |
||
344 | * Seek Bytes In File |
||
345 | * @param integer $bytes |
||
346 | * @param mixed|null extra |
||
347 | * @return int |
||
348 | */ |
||
349 | public function seekBytes(int $bytes, $extra = null) |
||
357 | |||
358 | /** |
||
359 | * Read Bytes From File |
||
360 | * @param integer $bytes |
||
361 | * @return bool|string |
||
362 | */ |
||
363 | public function readBytes(int $bytes) |
||
367 | |||
368 | /** |
||
369 | * Get file format |
||
370 | * @return string |
||
371 | */ |
||
372 | public function getFormat() : string |
||
376 | |||
377 | /** |
||
378 | * Get size of processed file |
||
379 | * @return int |
||
380 | */ |
||
381 | public function getProcessedSize() : int |
||
385 | |||
386 | /** |
||
387 | * Close file handle |
||
388 | */ |
||
389 | protected function closeFileHandle() |
||
396 | |||
397 | /** |
||
398 | * Get folder type |
||
399 | * @param string $folderName |
||
400 | * @return string |
||
401 | */ |
||
402 | protected function getFolderType(string $folderName) : string |
||
415 | |||
416 | /** |
||
417 | * Perform initial file processing |
||
418 | */ |
||
419 | protected function performInitialProcessing() |
||
428 | |||
429 | /** |
||
430 | * Create processor instance |
||
431 | * @param array $arguments |
||
432 | * @throws \Exception |
||
433 | */ |
||
434 | protected function createProcessor(array $arguments) |
||
461 | |||
462 | /** |
||
463 | * Load file structure |
||
464 | * @param string $fileName |
||
465 | * @return $this |
||
466 | */ |
||
467 | private function loadStructure(string $fileName) |
||
477 | } |
||
478 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.