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 Manager 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 Manager, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
32 | class Manager |
||
33 | { |
||
34 | use \Jaxon\Utils\Traits\Manager; |
||
35 | use \Jaxon\Utils\Traits\Config; |
||
36 | use \Jaxon\Utils\Traits\Cache; |
||
37 | use \Jaxon\Utils\Traits\Event; |
||
38 | use \Jaxon\Utils\Traits\Minifier; |
||
39 | use \Jaxon\Utils\Traits\Template; |
||
40 | use \Jaxon\Utils\Traits\Translator; |
||
41 | |||
42 | /** |
||
43 | * The response type. |
||
44 | * |
||
45 | * @var string |
||
46 | */ |
||
47 | const RESPONSE_TYPE = 'JSON'; |
||
48 | |||
49 | /** |
||
50 | * All plugins, indexed by priority |
||
51 | * |
||
52 | * @var array |
||
53 | */ |
||
54 | private $aPlugins = []; |
||
55 | |||
56 | /** |
||
57 | * Request plugins, indexed by name |
||
58 | * |
||
59 | * @var array |
||
60 | */ |
||
61 | private $aRequestPlugins = []; |
||
62 | |||
63 | /** |
||
64 | * Response plugins, indexed by name |
||
65 | * |
||
66 | * @var array |
||
67 | */ |
||
68 | private $aResponsePlugins = []; |
||
69 | |||
70 | /** |
||
71 | * An array of package names |
||
72 | * |
||
73 | * @var array |
||
74 | */ |
||
75 | private $aPackages = []; |
||
76 | |||
77 | /** |
||
78 | * Javascript confirm function |
||
79 | * |
||
80 | * @var \Jaxon\Request\Interfaces\Confirm |
||
81 | */ |
||
82 | private $xConfirm; |
||
83 | |||
84 | /** |
||
85 | * Default javascript confirm function |
||
86 | * |
||
87 | * @var \Jaxon\Request\Support\Confirm |
||
88 | */ |
||
89 | private $xDefaultConfirm; |
||
90 | |||
91 | /** |
||
92 | * Javascript alert function |
||
93 | * |
||
94 | * @var \Jaxon\Request\Interfaces\Alert |
||
95 | */ |
||
96 | private $xAlert; |
||
97 | |||
98 | /** |
||
99 | * Default javascript alert function |
||
100 | * |
||
101 | * @var \Jaxon\Request\Support\Alert |
||
102 | */ |
||
103 | private $xDefaultAlert; |
||
104 | |||
105 | /** |
||
106 | * Initialize the Jaxon Plugin Manager |
||
107 | */ |
||
108 | public function __construct() |
||
118 | |||
119 | /** |
||
120 | * Set the javascript confirm function |
||
121 | * |
||
122 | * @param \Jaxon\Request\Interfaces\Confirm $xConfirm The javascript confirm function |
||
123 | * |
||
124 | * @return void |
||
125 | */ |
||
126 | public function setConfirm(\Jaxon\Request\Interfaces\Confirm $xConfirm) |
||
130 | |||
131 | /** |
||
132 | * Get the javascript confirm function |
||
133 | * |
||
134 | * @return \Jaxon\Request\Interfaces\Confirm |
||
135 | */ |
||
136 | public function getConfirm() |
||
140 | |||
141 | /** |
||
142 | * Get the default javascript confirm function |
||
143 | * |
||
144 | * @return \Jaxon\Request\Support\Confirm |
||
145 | */ |
||
146 | public function getDefaultConfirm() |
||
150 | |||
151 | /** |
||
152 | * Set the javascript alert function |
||
153 | * |
||
154 | * @param \Jaxon\Request\Interfaces\Alert $xAlert The javascript alert function |
||
155 | * |
||
156 | * @return void |
||
157 | */ |
||
158 | public function setAlert(\Jaxon\Request\Interfaces\Alert $xAlert) |
||
162 | |||
163 | /** |
||
164 | * Get the javascript alert function |
||
165 | * |
||
166 | * @return \Jaxon\Request\Interfaces\Alert |
||
167 | */ |
||
168 | public function getAlert() |
||
172 | |||
173 | /** |
||
174 | * Get the default javascript alert function |
||
175 | * |
||
176 | * @return \Jaxon\Request\Support\Alert |
||
177 | */ |
||
178 | public function getDefaultAlert() |
||
182 | |||
183 | /** |
||
184 | * Inserts an entry into an array given the specified priority number |
||
185 | * |
||
186 | * If a plugin already exists with the given priority, the priority is automatically incremented until a free spot is found. |
||
187 | * The plugin is then inserted into the empty spot in the array. |
||
188 | * |
||
189 | * @param Plugin $xPlugin An instance of a plugin |
||
190 | * @param integer $nPriority The desired priority, used to order the plugins |
||
191 | * |
||
192 | * @return void |
||
193 | */ |
||
194 | private function setPluginPriority(Plugin $xPlugin, $nPriority) |
||
204 | |||
205 | /** |
||
206 | * Register a plugin |
||
207 | * |
||
208 | * Below is a table for priorities and their description: |
||
209 | * - 0 thru 999: Plugins that are part of or extensions to the jaxon core |
||
210 | * - 1000 thru 8999: User created plugins, typically, these plugins don't care about order |
||
211 | * - 9000 thru 9999: Plugins that generally need to be last or near the end of the plugin list |
||
212 | * |
||
213 | * @param Plugin $xPlugin An instance of a plugin |
||
214 | * @param integer $nPriority The plugin priority, used to order the plugins |
||
215 | * |
||
216 | * @return void |
||
217 | */ |
||
218 | public function registerPlugin(Plugin $xPlugin, $nPriority = 1000) |
||
254 | |||
255 | /** |
||
256 | * Register a package |
||
257 | * |
||
258 | * @param string $sPackageClass The package class name |
||
259 | * @param Closure $xClosure A closure to create package instance |
||
260 | * |
||
261 | * @return void |
||
262 | */ |
||
263 | public function registerPackage(string $sPackageClass, Closure $xClosure) |
||
268 | |||
269 | /** |
||
270 | * Generate a hash for all the javascript code generated by the library |
||
271 | * |
||
272 | * @return string |
||
273 | */ |
||
274 | private function generateHash() |
||
283 | |||
284 | /** |
||
285 | * Check if the current request can be processed |
||
286 | * |
||
287 | * Calls each of the request plugins and determines if the current request can be processed by one of them. |
||
288 | * If no processor identifies the current request, then the request must be for the initial page load. |
||
289 | * |
||
290 | * @return boolean |
||
291 | */ |
||
292 | public function canProcessRequest() |
||
303 | |||
304 | /** |
||
305 | * Process the current request |
||
306 | * |
||
307 | * Calls each of the request plugins to request that they process the current request. |
||
308 | * If any plugin processes the request, it will return true. |
||
309 | * |
||
310 | * @return boolean |
||
311 | */ |
||
312 | public function processRequest() |
||
331 | |||
332 | /** |
||
333 | * Register a function, event or callable object |
||
334 | * |
||
335 | * Call each of the request plugins and give them the opportunity to handle the |
||
336 | * registration of the specified function, event or callable object. |
||
337 | * |
||
338 | * @param array $aArgs The registration data |
||
339 | * |
||
340 | * @return mixed |
||
341 | */ |
||
342 | public function register($aArgs) |
||
354 | |||
355 | /** |
||
356 | * Get the base URI of the Jaxon library javascript files |
||
357 | * |
||
358 | * @return string |
||
359 | */ |
||
360 | private function getJsLibUri() |
||
370 | |||
371 | /** |
||
372 | * Get the extension of the Jaxon library javascript files |
||
373 | * |
||
374 | * The returned string is '.min.js' if the files are minified. |
||
375 | * |
||
376 | * @return string |
||
377 | */ |
||
378 | private function getJsLibExt() |
||
391 | |||
392 | /** |
||
393 | * Check if the javascript code generated by Jaxon can be exported to an external file |
||
394 | * |
||
395 | * @return boolean |
||
396 | */ |
||
397 | public function canExportJavascript() |
||
417 | |||
418 | /** |
||
419 | * Set the cache directory for the template engine |
||
420 | * |
||
421 | * @return void |
||
422 | */ |
||
423 | private function setTemplateCacheDir() |
||
430 | |||
431 | /** |
||
432 | * Get the HTML tags to include Jaxon javascript files into the page |
||
433 | * |
||
434 | * @return string |
||
435 | */ |
||
436 | public function getJs() |
||
480 | |||
481 | /** |
||
482 | * Get the HTML tags to include Jaxon CSS code and files into the page |
||
483 | * |
||
484 | * @return string |
||
485 | */ |
||
486 | View Code Duplication | public function getCss() |
|
509 | |||
510 | /** |
||
511 | * Get the correspondances between previous and current config options |
||
512 | * |
||
513 | * They are used to keep the deprecated config options working. |
||
514 | * They will be removed when the deprecated options will lot be supported anymore. |
||
515 | * |
||
516 | * @return array |
||
517 | */ |
||
518 | private function getOptionVars() |
||
538 | |||
539 | /** |
||
540 | * Get the javascript code for Jaxon client side configuration |
||
541 | * |
||
542 | * @return string |
||
543 | */ |
||
544 | private function getConfigScript() |
||
554 | |||
555 | /** |
||
556 | * Get the javascript code to be run after page load |
||
557 | * |
||
558 | * Also call each of the response plugins giving them the opportunity |
||
559 | * to output some javascript to the page being generated. |
||
560 | * |
||
561 | * @return string |
||
562 | */ |
||
563 | View Code Duplication | private function getReadyScript() |
|
584 | |||
585 | /** |
||
586 | * Get the javascript code to be sent to the browser |
||
587 | * |
||
588 | * Also call each of the request plugins giving them the opportunity |
||
589 | * to output some javascript to the page being generated. |
||
590 | * This is called only when the page is being loaded initially. |
||
591 | * This is not called when processing a request. |
||
592 | * |
||
593 | * @return string |
||
594 | */ |
||
595 | private function getAllScripts() |
||
605 | |||
606 | /** |
||
607 | * Get the javascript code to be sent to the browser |
||
608 | * |
||
609 | * Also call each of the request plugins giving them the opportunity |
||
610 | * to output some javascript to the page being generated. |
||
611 | * This is called only when the page is being loaded initially. |
||
612 | * This is not called when processing a request. |
||
613 | * |
||
614 | * @return string |
||
615 | */ |
||
616 | public function getScript() |
||
659 | |||
660 | /** |
||
661 | * Find the specified response plugin by name and return a reference to it if one exists |
||
662 | * |
||
663 | * @param string $sName The name of the plugin |
||
664 | * |
||
665 | * @return \Jaxon\Plugin\Response |
||
666 | */ |
||
667 | public function getResponsePlugin($sName) |
||
675 | |||
676 | /** |
||
677 | * Find the specified request plugin by name and return a reference to it if one exists |
||
678 | * |
||
679 | * @param string $sName The name of the plugin |
||
680 | * |
||
681 | * @return \Jaxon\Plugin\Request |
||
682 | */ |
||
683 | public function getRequestPlugin($sName) |
||
691 | } |
||
692 |
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.