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 EEH_Debug_Tools 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 EEH_Debug_Tools, and based on these observations, apply Extract Interface, too.
1 | <?php use EventEspresso\core\services\Benchmark; |
||
17 | class EEH_Debug_Tools |
||
18 | { |
||
19 | |||
20 | /** |
||
21 | * instance of the EEH_Autoloader object |
||
22 | * |
||
23 | * @var $_instance |
||
24 | * @access private |
||
25 | */ |
||
26 | private static $_instance; |
||
27 | |||
28 | /** |
||
29 | * @var array |
||
30 | */ |
||
31 | protected $_memory_usage_points = array(); |
||
32 | |||
33 | |||
34 | |||
35 | /** |
||
36 | * @singleton method used to instantiate class object |
||
37 | * @access public |
||
38 | * @return EEH_Debug_Tools |
||
39 | */ |
||
40 | public static function instance() |
||
48 | |||
49 | |||
50 | |||
51 | /** |
||
52 | * private class constructor |
||
53 | */ |
||
54 | private function __construct() |
||
73 | |||
74 | |||
75 | |||
76 | /** |
||
77 | * show_db_name |
||
78 | * |
||
79 | * @return void |
||
80 | */ |
||
81 | public static function show_db_name() |
||
92 | |||
93 | |||
94 | |||
95 | /** |
||
96 | * dump EE_Session object at bottom of page after everything else has happened |
||
97 | * |
||
98 | * @return void |
||
99 | */ |
||
100 | public function espresso_session_footer_dump() |
||
117 | |||
118 | |||
119 | |||
120 | /** |
||
121 | * List All Hooked Functions |
||
122 | * to list all functions for a specific hook, add ee_list_hooks={hook-name} to URL |
||
123 | * http://wp.smashingmagazine.com/2009/08/18/10-useful-wordpress-hook-hacks/ |
||
124 | * |
||
125 | * @param string $tag |
||
126 | * @return void |
||
127 | */ |
||
128 | public function espresso_list_hooked_functions($tag = '') |
||
154 | |||
155 | |||
156 | |||
157 | /** |
||
158 | * registered_filter_callbacks |
||
159 | * |
||
160 | * @param string $hook_name |
||
161 | * @return array |
||
162 | */ |
||
163 | public static function registered_filter_callbacks($hook_name = '') |
||
178 | |||
179 | |||
180 | |||
181 | /** |
||
182 | * captures plugin activation errors for debugging |
||
183 | * |
||
184 | * @return void |
||
185 | * @throws EE_Error |
||
186 | */ |
||
187 | public static function ee_plugin_activation_errors() |
||
227 | |||
228 | |||
229 | |||
230 | /** |
||
231 | * This basically mimics the WordPress _doing_it_wrong() function except adds our own messaging etc. |
||
232 | * Very useful for providing helpful messages to developers when the method of doing something has been deprecated, |
||
233 | * or we want to make sure they use something the right way. |
||
234 | * |
||
235 | * @access public |
||
236 | * @param string $function The function that was called |
||
237 | * @param string $message A message explaining what has been done incorrectly |
||
238 | * @param string $version The version of Event Espresso where the error was added |
||
239 | * @param string $applies_when a version string for when you want the doing_it_wrong notice to begin appearing |
||
240 | * for a deprecated function. This allows deprecation to occur during one version, |
||
241 | * but not have any notices appear until a later version. This allows developers |
||
242 | * extra time to update their code before notices appear. |
||
243 | * @param int $error_type |
||
244 | * @uses trigger_error() |
||
245 | */ |
||
246 | public function doing_it_wrong( |
||
297 | |||
298 | |||
299 | |||
300 | |||
301 | /** |
||
302 | * Logger helpers |
||
303 | */ |
||
304 | /** |
||
305 | * debug |
||
306 | * |
||
307 | * @param string $class |
||
308 | * @param string $func |
||
309 | * @param string $line |
||
310 | * @param array $info |
||
311 | * @param bool $display_request |
||
312 | * @param string $debug_index |
||
313 | * @param string $debug_key |
||
314 | * @throws EE_Error |
||
315 | * @throws \EventEspresso\core\exceptions\InvalidSessionDataException |
||
316 | */ |
||
317 | public static function log( |
||
343 | |||
344 | |||
345 | |||
346 | /** |
||
347 | * strip_objects |
||
348 | * |
||
349 | * @param array $info |
||
350 | * @return array |
||
351 | */ |
||
352 | public static function strip_objects($info = array()) |
||
374 | |||
375 | |||
376 | |||
377 | /** |
||
378 | * @param mixed $var |
||
379 | * @param string $var_name |
||
380 | * @param string $file |
||
381 | * @param int|string $line |
||
382 | * @param int $heading_tag |
||
383 | * @param bool $die |
||
384 | * @param string $margin |
||
385 | */ |
||
386 | public static function printv( |
||
387 | $var, |
||
388 | $var_name = '', |
||
389 | $file = '', |
||
390 | $line = '', |
||
391 | $heading_tag = 5, |
||
392 | $die = false, |
||
393 | $margin = '' |
||
394 | ) { |
||
395 | $var_name = ! $var_name ? 'string' : $var_name; |
||
396 | $var_name = ucwords(str_replace('$', '', $var_name)); |
||
397 | $is_method = method_exists($var_name, $var); |
||
398 | $var_name = ucwords(str_replace('_', ' ', $var_name)); |
||
399 | $result = $heading_tag > 3 && defined('EE_TESTS_DIR') |
||
400 | ? "\n" |
||
401 | :''; |
||
402 | $heading_tag = is_int($heading_tag) ? "h{$heading_tag}" : 'h5'; |
||
403 | $result .= EEH_Debug_Tools::heading($var_name, $heading_tag, $margin); |
||
404 | $result .= $is_method |
||
405 | ? EEH_Debug_Tools::grey_span('::') . EEH_Debug_Tools::orange_span($var . '()') |
||
406 | : EEH_Debug_Tools::grey_span(' : ') . EEH_Debug_Tools::orange_span($var); |
||
407 | $result .= EEH_Debug_Tools::file_and_line($file, $line); |
||
408 | $result .= EEH_Debug_Tools::headingX($heading_tag); |
||
409 | if ($die) { |
||
410 | die($result); |
||
411 | } |
||
412 | echo $result; |
||
413 | } |
||
414 | |||
415 | |||
416 | |||
417 | /** |
||
418 | * @param string $var_name |
||
419 | * @param string $heading_tag |
||
420 | * @param string $margin |
||
421 | * @return string |
||
422 | */ |
||
423 | protected static function heading($var_name = '', $heading_tag = 'h5', $margin = '') |
||
424 | { |
||
425 | if (defined('EE_TESTS_DIR')) { |
||
426 | return "\n{$var_name}"; |
||
427 | } |
||
428 | $margin = "25px 0 0 {$margin}"; |
||
429 | return '<' . $heading_tag . ' style="color:#2EA2CC; margin:' . $margin . ';"><b>' . $var_name . '</b>'; |
||
430 | } |
||
431 | |||
432 | |||
433 | |||
434 | /** |
||
435 | * @param string $heading_tag |
||
436 | * @return string |
||
437 | */ |
||
438 | protected static function headingX($heading_tag = 'h5') |
||
439 | { |
||
440 | if (defined('EE_TESTS_DIR')) { |
||
441 | return ''; |
||
442 | } |
||
443 | return '</' . $heading_tag . '>'; |
||
444 | } |
||
445 | |||
446 | |||
447 | |||
448 | /** |
||
449 | * @param string $content |
||
450 | * @return string |
||
451 | */ |
||
452 | protected static function grey_span($content = '') |
||
453 | { |
||
454 | if (defined('EE_TESTS_DIR')) { |
||
455 | return $content; |
||
456 | } |
||
457 | return '<span style="color:#999">' . $content . '</span>'; |
||
458 | } |
||
459 | |||
460 | |||
461 | |||
462 | /** |
||
463 | * @param string $file |
||
464 | * @param int $line |
||
465 | * @return string |
||
466 | */ |
||
467 | protected static function file_and_line($file, $line) |
||
468 | { |
||
469 | if ($file === '' || $line === '' || defined('EE_TESTS_DIR')) { |
||
470 | return ''; |
||
471 | } |
||
472 | return '<br /><span style="font-size:9px;font-weight:normal;color:#666;line-height: 12px;">' |
||
473 | . $file |
||
474 | . '<br />line no: ' |
||
475 | . $line |
||
476 | . '</span>'; |
||
477 | } |
||
478 | |||
479 | |||
480 | |||
481 | /** |
||
482 | * @param string $content |
||
483 | * @return string |
||
484 | */ |
||
485 | protected static function orange_span($content = '') |
||
492 | |||
493 | |||
494 | |||
495 | /** |
||
496 | * @param mixed $var |
||
497 | * @return string |
||
498 | */ |
||
499 | protected static function pre_span($var) |
||
509 | |||
510 | |||
511 | |||
512 | /** |
||
513 | * @param mixed $var |
||
514 | * @param string $var_name |
||
515 | * @param string $file |
||
516 | * @param int|string $line |
||
517 | * @param int $heading_tag |
||
518 | * @param bool $die |
||
519 | */ |
||
520 | public static function printr( |
||
560 | |||
561 | |||
562 | |||
563 | /******************** deprecated ********************/ |
||
564 | |||
565 | |||
566 | |||
567 | /** |
||
568 | * @deprecated 4.9.39.rc.034 |
||
569 | */ |
||
570 | public function reset_times() |
||
574 | |||
575 | |||
576 | |||
577 | /** |
||
578 | * @deprecated 4.9.39.rc.034 |
||
579 | * @param null $timer_name |
||
580 | */ |
||
581 | public function start_timer($timer_name = null) |
||
585 | |||
586 | |||
587 | |||
588 | /** |
||
589 | * @deprecated 4.9.39.rc.034 |
||
590 | * @param string $timer_name |
||
591 | */ |
||
592 | public function stop_timer($timer_name = '') |
||
596 | |||
597 | |||
598 | |||
599 | /** |
||
600 | * @deprecated 4.9.39.rc.034 |
||
601 | * @param string $label The label to show for this time eg "Start of calling Some_Class::some_function" |
||
602 | * @param boolean $output_now whether to echo now, or wait until EEH_Debug_Tools::show_times() is called |
||
603 | * @return void |
||
604 | */ |
||
605 | public function measure_memory($label, $output_now = false) |
||
609 | |||
610 | |||
611 | |||
612 | /** |
||
613 | * @deprecated 4.9.39.rc.034 |
||
614 | * @param int $size |
||
615 | * @return string |
||
616 | */ |
||
617 | public function convert($size) |
||
621 | |||
622 | |||
623 | |||
624 | /** |
||
625 | * @deprecated 4.9.39.rc.034 |
||
626 | * @param bool $output_now |
||
627 | * @return string |
||
628 | */ |
||
629 | public function show_times($output_now = true) |
||
633 | |||
634 | |||
635 | |||
636 | /** |
||
637 | * @deprecated 4.9.39.rc.034 |
||
638 | * @param string $timer_name |
||
639 | * @param float $total_time |
||
640 | * @return string |
||
641 | */ |
||
642 | public function format_time($timer_name, $total_time) |
||
646 | |||
647 | |||
648 | |||
649 | } |
||
650 | |||
651 | |||
686 |
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.
Let’s take a look at an example:
As you can see in this example, the array
$myArray
is initialized the first time when the foreach loop is entered. You can also see that the value of thebar
key is only written conditionally; thus, its value might result from a previous iteration.This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.