raya code quality guidelines - enhancing readability

56
Raya Code Quality Raya Code Quality Guidelines Guidelines Enhancing Readability Raya Software By: Abdel Hady Muhammad

Upload: abdel-hady-muhammad

Post on 05-Dec-2014

196 views

Category:

Software


0 download

DESCRIPTION

A clean code guide towards a better readability .. a better working experience :)

TRANSCRIPT

  • 1. Raya Code QualityRaya Code Quality GuidelinesGuidelines Enhancing Readability Raya Software By: Abdel Hady Muhammad
  • 2. Agenda Clean Code Meaningful Names Methods Error Handling Raya Software
  • 3. Clean CodeClean Code The Why Question ??? Raya Software
  • 4. Clean code Introduction to Raya Guide There will be a code Code Quality Measurement Bad Code The Boy Scout Rule Our Attitude We are Authors Clean CodeRaya Software
  • 5. Introduction to Raya Guide The need How to read Clean CodeRaya Software
  • 6. There will be a code Generated code, only? If so let the customer generate the program for him self New languages & technologies may get closer to requirements, but: We will never get rid of code Clean CodeRaya Software
  • 7. Code Quality Measurement WTFs/minute Clean CodeRaya Software
  • 8. Bad Code Rush + Later = Mess (of Bad Code) Rush: it is a market nature; we cant get rid of Later: enhancing it will enhance the formula Challenge is: A working mess is better than nothing Cant fully disagree, but look at team productivity if we insist on saying so: Clean CodeRaya Software
  • 9. Bad Code With Later team productivity will be: So keep in mind LeBlancs law: Later Equals Never Clean CodeRaya Software
  • 10. The Boy Scout Rule We may face Bad Code in: Projects written by others Projects we wrote in a rush So there always be a Bad Code The Solution is The Boy Scout Rule: Leave the campground cleaner than you found it Which means: check in cleaner code than you checked it out Imagine working in a project where code simply got better Clean CodeRaya Software
  • 11. Our Attitude Clean Code is a matter of attitude more than being a matter of knowledge Managers passion? Delivery time Customers passion? Requirement & Cost Our passion? ... [Mess = Miss ] Delivery time [Mess = Miss ] Requirement [Mess = Miss ] Team Productivity Clean CodeRaya Software Clean Code
  • 12. We are Authors @author field of a Javadoc is pointing at us The author is writing for .. Reader No way to write code without read the ratio of time spent reading vs. writing is well over 10:1 Making it easy to read makes it easier to write Professionals choose Paperback Model not the Academic Model Clean CodeRaya Software
  • 13. Meaningful NamesMeaningful Names The Who Question ??? Raya Software
  • 14. Meaningful Names Introduction Rule #1: Use Intention-Revealing Names Rule #2: Avoid Disinformation Rule #3: Make Meaningful Distinction Rule #4: Use Pronounceable Names Rule #5: Use Searchable Names Rule #6: Avoid Encodings Rule #7: Avoid Mental Mapping Rule #8: Dont be Cute Rule #9: Pick One Word per Concept Rule #12: Dont Add Extra-free Context Conclusion Meaningful NamesRaya Software
  • 15. Introduction Names are everywhere We name our: Variables Methods Arguments Classes Packages Source files Directories Jar files WAR & EAR files Meaningful NamesRaya Software
  • 16. Rule #1 Use Intention-Revealing Names Meaningful NamesRaya Software int d; // elapsed time in days Very Bad int elapsedTimeInDays; int daysSinceCreation; int daysSinceModification; int fileAgeInDays; Good Motive: If a name requires a comment, then the name does not reveal its intent.
  • 17. Rule #2 Avoid Disinformation Meaningful NamesRaya Software Variable name Motive accountList Dont use this name unless it is already a List object XYZControllerForEfficientHandlingOfStrings XYZControllerForEfficientStorageOfStrings how long will it take to see the difference between them Karakter will never be found when the programmer searches for character int a = l; if ( O == l ) a = O1; else l = 01; uppercase O or just Zero ? lower case L or just one ? - liar if you answer it without changing the code font
  • 18. Rule #3 Make Meaningful Distinction Meaningful NamesRaya Software public static void copyChars(char a1[] , char a2[]) { for (int i = 0; i < a1.length; i++) { a2[i] = a1[i]; } } Bad public static void copyChars(char[] source , char[] destination) { for (int i = 0; i < source.length; i++) { destination[i] = source[i]; } } Good Motive: Number-series names are not only disinformative but they are noninformative at all
  • 19. Rule #4 Use Pronounceable Names Try to read the following variable genymdhms Now we sounds like Idiots So seriously the reason for this rule is not to being an idiot Meaningful NamesRaya Software
  • 20. Rule #5 Use Searchable Names Single-letter names can ONLY be used as local variables inside short methods. The length of a name should correspond to the size of its scope Meaningful NamesRaya Software 7 e Very Bad DAYS_PER_WEEK week Good Motive: Single-letter names and numeric constants are not easy to locate across a body of text. There can be no worse reason for using the name c than because a and b were already taken.
  • 21. Rule #6 Avoid Encodings Member Variables Prefixing each member variable with m_ Meaningful NamesRaya Software
  • 22. Rule #6 Avoid Encodings Interfaces & Implementation Meaningful NamesRaya Software Interface IShapeFactory {...} Class ShapeFactory implements IShapeFactory {...} Very Bad Interface ShapeFactory {...} Class ShapeFactoryImp implements ShapeFactory {...} Good Motive: If I must encode either the interface or the implementation, I choose the implementation. I dont want my users knowing that Im handing them an interface. I just want them to know that its a ShapeFactory.
  • 23. Rule #7 Avoid Mental Mapping Like using r instead of url So dont be Smart, but Be Professional When to Use Solution Domain Names When it is more close to patterns of computer science concepts When to Use Problem Domain Names When it is more close to business Meaningful NamesRaya Software
  • 24. Rule #8 Dont Be Cute Like using HolyHandGrenade() instead of DeleteItems() Names based on cultural base or sense of humor will only be remembered by people who know it Meaningful NamesRaya Software
  • 25. Rule #9 Pick One Word per Concept Like using fetch(), retrieve(), and get() in the same layer How on earth should the caller know which method to call ? !!! Meaningful NamesRaya Software
  • 26. Rule #12 Dont Add Extra-free Context In a Gas Station Deluxe application, it is a bad idea to prefix every class with GSD Meaningful NamesRaya Software
  • 27. Conclusion Dont be afraid of renaming things People will be grateful if you do so Let Refactoring Tools Help you Believe me, it will pay off in the short run and continue to pay in the long run Meaningful NamesRaya Software
  • 28. Who is this? Clean CodeRaya Software
  • 29. MethodsMethods The How Question ??? Raya Software
  • 30. Methods Introduction Rule #1: Small Rule #2: Do One Thing Rule #3: One Level of Abstraction per Method Rule #4: Avoid Switch Statements Rule #5: Use Descriptive Names Rule #6: Minimize Method Arguments Rule #7: Have No Side Effects Rule #9: Separate Command from Query Some Structured Programming Concepts Dont Repeat Yourself (DRY) MethodsRaya Software
  • 31. Introduction Please, read this method and see how much sense you can get of it in 3 minutes Now see the coming refactored version of it MethodsRaya Software
  • 32. Introduction Surprise, isnt it?, So how we can do it ? MethodsRaya Software HtmlUtil.java (Refactored) public static String renderPageWithSetupsAndTeardowns( PageData pageData, boolean isSuite ) throws Exception { boolean isTestPage = pageData.hasAttribute("Test"); if (isTestPage) { WikiPage testPage = pageData.getWikiPage(); StringBuffer newPageContent = new StringBuffer(); includeSetupPages(testPage, newPageContent, isSuite); newPageContent.append(pageData.getContent()); includeTeardownPages(testPage, newPageContent, isSuite); pageData.setContent(newPageContent.toString()); } return pageData.getHtml(); }
  • 33. Rule #1: Small First: methods should be small Second: they should be smaller than that Im not kidding They should be a Screen-Full Or should hardly ever be 20 lines long After applying this on the refactored version, look on the re-refactored one: MethodsRaya Software
  • 34. Rule #1: Small Again, s-u-r-p-r-i-s-e MethodsRaya Software HtmlUtil.java (re-Refactored) public static String renderPageWithSetupsAndTeardowns( PageData pageData, boolean isSuite) throws Exception { if (isTestPage(pageData)) includeSetupAndTeardownPages(pageData, isSuite); return pageData.getHtml(); }
  • 35. Rule #2: Do One Thing FUNCTIONS SHOULD DO ONE THING. THEY SHOULD DO IT WELL. THEY SHOULD DO IT ONLY. Look at the refactored version, its doing 3 things: Determining whether the page is a test page. If so, including setups and teardowns. Rendering the page in HTML. Which just violates our rule MethodsRaya Software
  • 36. Rule #3: One Level of Abstraction per Method mixing levels of abstraction within a method is always confusing Readers may not be able to tell whether a particular expression is an essential concept or a detail !!! MethodsRaya Software
  • 37. Rule #4: Avoid Switch Statements First of all it violates the Do One Thing rule As a work around: Bury the switch statement in the basement of an ABSTRACT FACTORY (GOF pattern) Sometimes we cant get rid of it, but we should try MethodsRaya Software
  • 38. Rule #5: Use Descriptive Names As covered in the last section Dont be afraid to make a name long. Dont be afraid to spend time choosing a name. MethodsRaya Software
  • 39. Rule #6: Minimize Method Arguments From the Guide MethodsRaya Software
  • 40. Rule #7: Have No Side Effects Try to spot any side effect in the following MethodsRaya Software UserValidator.java public class UserValidator { private Cryptographer cryptographer; public boolean checkPassword(String userName, String password) { User user = UserGateway.findByName(userName); if (user != User.NULL) { String codedPhrase = user.getPhraseEncodedByPassword(); String phrase = cryptographer.decrypt(codedPhrase, password); if ("Valid Password".equals(phrase)) { Session.initialize(); return true; } } return false; } }
  • 41. Rule #7: Have No Side Effects Its name implies checking the password But it also initializing the session !!!!!!!! Which may cause data lose if someone call it without knowing this Solution: if we cant divide it, then just tell the caller that you are doing so and rename it: checkPasswordAndInitializeSession() MethodsRaya Software
  • 42. Rule #9: Separate Command from Query Methods should either do something or answer something MethodsRaya Software if (set("username", "unclebob"))... Bad if (attributeExists("username")) { setAttribute("username", "unclebob"); ... } Good Motive: Is it asking whether the username attribute was previously set to unclebob? Or is it asking whether the username attribute was successfully set to unclebob? Solution: You can rename it setAndCheckIfExists, but that doesnt much help the readability of the if statement. But the real solution is to separate the command from the query so that the ambiguity cannot occur.
  • 43. Some Structured Programming Concepts Edsger Dijkstra said that every function, and every block within a function, should have one entry and one exit. Only one return statement in a method. No break or continue statements in a loop. And never, ever, any goto statements. MethodsRaya Software
  • 44. Dont Repeat Yourself (DRY) Duplication may be the root of all evil in software In our method the following was repeated 4 times through it: SetUp SuiteSetUp TearDown SuiteTearDown Now look at the final version MethodsRaya Software
  • 45. Error HandlingError Handling The Teeeet Question ??? Raya Software
  • 46. Error Handling Introduction Rule #1: Prefer exceptions to Returning Error Codes Rule #11: Extract Try/Catch Blocks Rule #3: Use Unchecked Exceptions Rule #4: Dont Eat the Exception Rule #5: Resist Temptation to write a Single Catchall Rule #6: Always use Catchall after handling known ones Rule #8: Dont Return NULL Rule #9: Dont Pass Null Error HandlingRaya Software
  • 47. Introduction It might seem odd to have a section about Error Handling when talking about readability Some Programs are dominated by Error Handling Error handling is important, but if it covers the logic, then its wrong. Error HandlingRaya Software
  • 48. Rule #1: Prefer exceptions to Returning Error Codes Error HandlingRaya Software if (deletePage(page) == E_OK) { if (registry.deleteReference(page.name) == E_OK) { if (configKeys.deleteKey(page.name.makeKey()) == E_OK){ logger.log("page deleted"); } else { logger.log("configKey not deleted"); } } else { logger.log("deleteReference from registry failed"); } } else { logger.log("delete failed"); return E_ERROR; } Bad try { deletePage(page); registry.deleteReference(page.name); configKeys.deleteKey(page.name.makeKey()); } catch (Exception e) { logger.log(e.getMessage()); } Good Motive: Error Codes awful nested IFs But using Exceptions now, we can read the normal flow
  • 49. Rule #11:Extract Try/Catch Blocks Error HandlingRaya Software try { deletePage(page); registry.deleteReference(page.name); configKeys.deleteKey(page.name.makeKey()); } catch (Exception e) { logger.log(e.getMessage()); } Not so good public void delete(Page page) { try { deletePageAndAllReferences(page); } catch (Exception e) { logError(e); } } private void deletePageAndAllReferences(Page page) throws Exception {.} private void logError(Exception e) {.} Good Motive: The delete is all about error processing deletePageAndAllReferences is all about the processes of deleting a page, which provides a nice separation that makes the code easier to understand and modify.
  • 50. Rule #3: Use Unchecked Exceptions The debate is over !!!!!! Why not using Checked Exceptions Increasing error handling in many parts of our system Breaking or better said destroying Encapsulation When to use Checked Exceptions: If the caller knows & wants how to handle it When dealing with Critical Systems or libraries Error HandlingRaya Software
  • 51. Rule #4: Dont Eat the Exception Error HandlingRaya Software try { callBadMethod(); } catch (Exception ex) { } bad try { callBadMethod(); } catch (Exception ex) { ex.printStackTrace(); } Good Motive: At least use the printStackTrace method or you will never know anything about it. Moreover to do is logging it.
  • 52. Rule #5: Resist Temptation to write a Single Catchall Exception handlers that trap many errors at once will probably reduce the reliability of your program More probably the an exception will be caught and the handler will not know about it. Error HandlingRaya Software
  • 53. Rule #6: Always use Catchall after handling known ones You cant be sure that the exceptions you handled is the only ones So append them by the default catchall to protect your system. Error HandlingRaya Software
  • 54. Rule #8: Dont Return NULL Look how NULL makes code awful: Solution: Returning a special case object. Wrapping our method with another that throws exception. The only method that returns NULL is the one you didnt implement Error HandlingRaya Software UserValidator.java public void registerItem(Item item) { if (item != null) { ItemRegistry registry = peristentStore.getItemRegistry(); if (registry != null) { Item existing = registry.getItem(item.getID()); if (existing.getBillingPeriod().hasRetailOwner()) { existing.register(item); } } } }
  • 55. Rule #9: Dont Pass NULL If returning null from methods is bad, then passing null into methods is far worse Passing NULL should be handled inside the method or NullPointerException will be thrown Unless the used API is passing NULL, you should avoid it whenever possible Error HandlingRaya Software
  • 56. Thank youThank you Raya Software