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 Simple 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 Simple, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
43 | class Simple |
||
44 | { |
||
45 | |||
46 | /** |
||
47 | * The actions unique serial. |
||
48 | * |
||
49 | * @var string |
||
50 | */ |
||
51 | protected $serial; |
||
52 | |||
53 | /** |
||
54 | * The system logger implementation. |
||
55 | * |
||
56 | * @var \Psr\Log\LoggerInterface |
||
57 | */ |
||
58 | protected $systemLogger; |
||
59 | |||
60 | /** |
||
61 | * The RegistryProcessor instance to handle running threads. |
||
62 | * |
||
63 | * @var \TechDivision\Import\Services\RegistryProcessorInterface |
||
64 | */ |
||
65 | protected $registryProcessor; |
||
66 | |||
67 | /** |
||
68 | * The processor to read/write the necessary import data. |
||
69 | * |
||
70 | * @var \TechDivision\Import\Services\ImportProcessorInterface |
||
71 | */ |
||
72 | protected $importProcessor; |
||
73 | |||
74 | /** |
||
75 | * The system configuration. |
||
76 | * |
||
77 | * @var \TechDivision\Import\ConfigurationInterface |
||
78 | */ |
||
79 | protected $configuration; |
||
80 | |||
81 | /** |
||
82 | * Set's the unique serial for this import process. |
||
83 | * |
||
84 | * @param string $serial The unique serial |
||
85 | * |
||
86 | * @return void |
||
87 | */ |
||
88 | public function setSerial($serial) |
||
92 | |||
93 | /** |
||
94 | * Return's the unique serial for this import process. |
||
95 | * |
||
96 | * @return string The unique serial |
||
97 | */ |
||
98 | public function getSerial() |
||
102 | |||
103 | /** |
||
104 | * Set's the system logger. |
||
105 | * |
||
106 | * @param \Psr\Log\LoggerInterface $systemLogger The system logger |
||
107 | * |
||
108 | * @return void |
||
109 | */ |
||
110 | public function setSystemLogger(LoggerInterface $systemLogger) |
||
114 | |||
115 | /** |
||
116 | * Return's the system logger. |
||
117 | * |
||
118 | * @return \Psr\Log\LoggerInterface The system logger instance |
||
119 | */ |
||
120 | public function getSystemLogger() |
||
124 | |||
125 | /** |
||
126 | * Sets's the RegistryProcessor instance to handle the running threads. |
||
127 | * |
||
128 | * @param \TechDivision\Import\Services\RegistryProcessorInterface $registryProcessor The registry processor instance |
||
129 | * |
||
130 | * @return void |
||
131 | */ |
||
132 | public function setRegistryProcessor(RegistryProcessorInterface $registryProcessor) |
||
136 | |||
137 | /** |
||
138 | * Return's the RegistryProcessor instance to handle the running threads. |
||
139 | * |
||
140 | * @return \TechDivision\Import\Services\RegistryProcessor The registry processor instance |
||
141 | */ |
||
142 | public function getRegistryProcessor() |
||
146 | |||
147 | /** |
||
148 | * Set's the import processor instance. |
||
149 | * |
||
150 | * @param \TechDivision\Import\Services\ImportProcessorInterface $importProcessor The import processor instance |
||
151 | * |
||
152 | * @return void |
||
153 | */ |
||
154 | 1 | public function setImportProcessor(ImportProcessorInterface $importProcessor) |
|
158 | |||
159 | /** |
||
160 | * Return's the import processor instance. |
||
161 | * |
||
162 | * @return \TechDivision\Import\Services\ImportProcessorInterface The import processor instance |
||
163 | */ |
||
164 | 1 | public function getImportProcessor() |
|
168 | |||
169 | /** |
||
170 | * Set's the system configuration. |
||
171 | * |
||
172 | * @param \TechDivision\Import\ConfigurationInterface $configuration The system configuration |
||
173 | * |
||
174 | * @return void |
||
175 | */ |
||
176 | public function setConfiguration(ConfigurationInterface $configuration) |
||
180 | |||
181 | /** |
||
182 | * Return's the system configuration. |
||
183 | * |
||
184 | * @return \TechDivision\Import\ConfigurationInterface The system configuration |
||
185 | */ |
||
186 | public function getConfiguration() |
||
190 | |||
191 | /** |
||
192 | * Return's the prefix for the import files. |
||
193 | * |
||
194 | * @return string The prefix |
||
195 | */ |
||
196 | protected function getPrefix() |
||
200 | |||
201 | /** |
||
202 | * Return's the source directory that has to be watched for new files. |
||
203 | * |
||
204 | * @return string The source directory |
||
205 | */ |
||
206 | protected function getSourceDir() |
||
210 | |||
211 | /** |
||
212 | * Parse the temporary upload directory for new files to be imported. |
||
213 | * |
||
214 | * @return void |
||
215 | * @throws \Exception Is thrown, if the import process can't be finished successfully |
||
216 | */ |
||
217 | public function import() |
||
259 | |||
260 | /** |
||
261 | * This method start's the import process by initializing |
||
262 | * the status and appends it to the registry. |
||
263 | * |
||
264 | * @return void |
||
265 | */ |
||
266 | protected function start() |
||
287 | |||
288 | /** |
||
289 | * Prepares the global data for the import process. |
||
290 | * |
||
291 | * @return void |
||
292 | */ |
||
293 | protected function setUp() |
||
356 | |||
357 | /** |
||
358 | * Process all the subjects defined in the system configuration. |
||
359 | * |
||
360 | * @return void |
||
361 | * @throws \Exception Is thrown, if one of the subjects can't be processed |
||
362 | */ |
||
363 | protected function processSubjects() |
||
393 | |||
394 | /** |
||
395 | * Process the subject with the passed name/identifier. |
||
396 | * |
||
397 | * We create a new, fresh and separate subject for EVERY file here, because this would be |
||
398 | * the starting point to parallelize the import process in a multithreaded/multiprocessed |
||
399 | * environment. |
||
400 | * |
||
401 | * @param \TechDivision\Import\Configuration\Subject $subject The subject configuration |
||
402 | * |
||
403 | * @return void |
||
404 | * @throws \Exception Is thrown, if the subject can't be processed |
||
405 | */ |
||
406 | protected function processSubject($subject) |
||
439 | |||
440 | /** |
||
441 | * Factory method to create new handler instances. |
||
442 | * |
||
443 | * @param \TechDivision\Import\Configuration\Subject $subject The subject configuration |
||
444 | * |
||
445 | * @return object The handler instance |
||
446 | */ |
||
447 | public function subjectFactory($subject) |
||
477 | |||
478 | /** |
||
479 | * Lifecycle callback that will be inovked after the |
||
480 | * import process has been finished. |
||
481 | * |
||
482 | * @return void |
||
483 | * @throws \Exception Is thrown, if the |
||
484 | */ |
||
485 | protected function archive() |
||
549 | |||
550 | /** |
||
551 | * Removes the passed directory recursively. |
||
552 | * |
||
553 | * @param string $src Name of the directory to remove |
||
554 | * |
||
555 | * @return void |
||
556 | */ |
||
557 | protected function removeDir($src) |
||
579 | |||
580 | /** |
||
581 | * Lifecycle callback that will be inovked after the |
||
582 | * import process has been finished. |
||
583 | * |
||
584 | * @return void |
||
585 | * @throws \Exception Is thrown, if the |
||
586 | */ |
||
587 | protected function tearDown() |
||
590 | |||
591 | /** |
||
592 | * This method finishes the import process and cleans the registry. |
||
593 | * |
||
594 | * @return void |
||
595 | */ |
||
596 | protected function finish() |
||
600 | } |
||
601 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.