clean code and refactoring
Post on 16-Apr-2017
61.308 Views
Preview:
TRANSCRIPT
Clean Code and Refactoring
Yuriy Gerasimovemail: yuri.gerasimov@gmail.comtwitter: ygerasimovskype: yuriy_gerasimov
d.o.: http://drupal.org/user/257311
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
Learn PHP and Drupal functions
Build array (5 => 5, 6 => 6, , 10 => 10);drupal_map_assoc(range(5, 10));
Sort form elementuasort($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) {}
Names
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()
Constants
Use constants to describe what static vars meanif ($user->uid == 2) if ($user->uid == USER_SUPER_ADMIN_UID )if ($user->uid == self::USER_SUPER_ADMIN_UID)
Function names
(double underscore)
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!
Functions
Group arguments to eliminate number of arguments
Pass structures that function is going to alter if results are complex
Functions
Groupped arguments, apply default values
Function
Helper functions underscore prefix (_menu_delete_item())
Group helper functions into classes with static methods. Autoloading.
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
Spaghetti code
Return result early (continue and break cycles)
Spaghetti code (refactored)
Use switch construction
(example from locale.inc)
Return conditions
simply return value (return ($a == $b); )
backup_migrate/includes/destinations.file.inc
Long conditions
one condition per line
operators in front
identation
Use Exceptions
Use Exceptions
_io_checkout_page_ajax_validate__if_email_exists()
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()
Organize your code right
Separate files
Follow traditions
1000 lines you do it wrong
Organize your code right
Sort by source and not by name
First hooks implementations, then helpers
Use IDE collapsed view
Do not Repeat Yourself (DRY)
panels/includes/plugins.inc
DRY
panels/includes/plugins.inc
Functional programming
anonymous functions (closures) php 5.3.0
variables can be functions
functions can be passed as arguments
Functional programming
Functional used
Functional used
Refactoring loves tests
Some tests better than no tests at all
Use DrupalUnitTestCasefor unit testing (fast)
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
top related