Clean code and refactoring

61,307 views

Published on

Some practical recepies how to make your code cleaner and more readable for other developers (an yourself).

Clean code and refactoring

  1. 1. Clean Code and RefactoringYuriy Gerasimovemail: yuri.gerasimov@gmail.comtwitter: ygerasimovskype: yuriy_gerasimovd.o.: http://drupal.org/user/257311
  2. 2. Disclaimer● Not rules but recepies● You are not the last person who will look at this code● Leave the code in better shape that you found it● Debates are welcome
  3. 3. Learn PHP and Drupal functions● Build array (5 => 5, 6 => 6, …, 10 => 10); – drupal_map_assoc(range(5, 10));● Sort form element – uasort($form, element_sort); // by #weight – uasort($form, element_sort_by_title);● Validation: valid_email_address(), valid_url()● Get all keys not prefixed with # for (element_children($form) as $key) {}
  4. 4. Names
  5. 5. Names● Variables, classes – nouns. Methods, functions – verbs● Shorter variable name for local scope ($i)● One name per concept ($user, $account, $person, $site_visitor)● Domain names ($student, $course, $lesson...)● Patterns names (singleton, visitor …)● Funciton name prefixes isSomething(), setSomething(), getSomething(), doSomething()
  6. 6. Constants● Use constants to describe what static vars mean if ($user->uid == 2) if ($user->uid == USER_SUPER_ADMIN_UID ) if ($user->uid == self::USER_SUPER_ADMIN_UID)
  7. 7. Function names(double underscore)
  8. 8. Functions● Functions should do one thing and be small and clean. Example menu_execute_active_handler(): – Checks whether site is online or not – Executes menu callback – Deliver callback result● _menu_router_build() has more than 200 lines!
  9. 9. Functions● Group arguments to eliminate number of arguments● Pass structures that function is going to alter if results are complex
  10. 10. Functions● Groupped arguments, apply default values
  11. 11. Function● Helper functions underscore prefix (_menu_delete_item())● Group helper functions into classes with static methods. Autoloading.
  12. 12. Comments● Comments get outdated first!● Comments should be written when we fail to find good variables / function names● Think twice about names before writing a comment explaining your intentions● Why it is done this way and not What is this
  13. 13. Spaghetti code● Return result early (continue and break cycles)
  14. 14. Spaghetti code (refactored)
  15. 15. Use switch construction● (example from locale.inc)
  16. 16. Return conditions● simply return value (return ($a == $b); )● backup_migrate/includes/destinations.file.inc
  17. 17. Long conditions● one condition per line● operators in front● identation
  18. 18. Use Exceptions
  19. 19. Use Exceptions● _io_checkout_page_ajax_validate__if_email_exists()
  20. 20. Use Polymorphism● D8 plugins system● Views handlers● Take a look at function names in form.inc: – form_type_checkbox_value(), theme_checkbox(), form_process_checkbox() – form_type_select_value(), theme_select(), form_process_select()
  21. 21. Organize your code right● Separate files● Follow traditions● 1000 lines – you do it wrong
  22. 22. Organize your code right● Sort by source and not by name● First hooks implementations, then helpers
  23. 23. Use IDE collapsed view
  24. 24. Do not Repeat Yourself (DRY)● panels/includes/plugins.inc
  25. 25. DRY● panels/includes/plugins.inc
  26. 26. Functional programming● anonymous functions (closures) php 5.3.0● variables can be functions● functions can be passed as arguments
  27. 27. Functional programming
  28. 28. Functional used
  29. 29. Functional used
  30. 30. Refactoring loves tests● Some tests better than no tests at all● Use DrupalUnitTestCase for unit testing (fast)
  31. 31. To read● Robert C. Martin. Clean Code: A Handbook of Agile Software Craftsmanship● Martin Fowler. Refactoring: Improving the Design of Existing Code● http://www.slideshare.net/rdohms/bettercode- phpbenelux212alternate● http://london2011.drupal.org/conference/sessions/code- stinks● http://chicago2011.drupal.org/sessions/aphorisms-api- design

×