Your SlideShare is downloading. ×
Clean code
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Clean code

799
views

Published on

My talk about Robert C. Martin's book "Clean Code: A Handbook of Agile Software Craftsmanship".

My talk about Robert C. Martin's book "Clean Code: A Handbook of Agile Software Craftsmanship".


0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
799
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Clean CodeBe a little more careful with the code you write!Ana Cortés Corbalán05.02.2013
  • 2. What? Why? How?05.02.2013 2 www.consol.com
  • 3. The only valid measurement of code quality: WTFs/minute05.02.2013 3 www.consol.com
  • 4. What is Clean Code?§  Simple §  Efficient§  No duplications §  Elegant§  Direct §  Focused§  With tests §  Minimal dependencies§  It was written by someone who cares§  ...§  Any fool can write code that a computer can understand. Good programmers write code that humans can understand. - Martin Fowler05.02.2013 4 www.consol.com
  • 5. Why is clean code so important?§  Easier to read§  Easier to understand§  Easier to change §  Add new features §  Find and fix bugs§  Cheaper to maintain§  Code quality is part of software quality05.02.2013 5 www.consol.com
  • 6. Use Intention-Revealing Names§  int d;!§  int days;!§  int days; //days since creation!§  int daysSinceCreation;!05.02.2013 6 www.consol.com
  • 7. Use Intention-Revealing Names§  What is the purpose? public List<int[]> getValues() {! List<int[]> list1 = new ArrayList<int[]>();! for (int[] x : theList)! if (x[0] == 4) list1.add(x);! return list1;! }!05.02.2013 7 www.consol.com
  • 8. Use Intention-Revealing Names§  Better? ! public List<Cell> getFlaggedCells() {! List<Cell> flaggedCells = new ArrayList<Cell>();! for (Cell cell : gameBoard) ! if (cell.isFlagged()) flaggedCells.add(cell);! return flaggedCells;! }! !05.02.2013 8 www.consol.com
  • 9. Don´t talk in code – Use Pronounceable Names class DtaRcrd102 {
 private Date genymdhms;
 private Date modymdhms;
 private final String pszqint = "102"; /* ... */ ! }!§  Better? class Customer {
 private Date generationTimestamp; ! private Date modificationTimestamp; ! private final String recordId = "102"; /* ... */ ! }!05.02.2013 9 www.consol.com
  • 10. More recommendations...§  Class names Customer, Account, AddressParser, ...§  Method names postPayment, deletePage, ....§  When constructors are overloaded... new Complex(23.0);! Complex.fromRealNumber(23.0); !§  Pick one word per concept get, fetch, retrieve...§  Don´t be cute. Jokes out of the code. public void saveTheUniverse() {...}05.02.2013 10 www.consol.com
  • 11. Bad Comments§  Redundant, noise, irrelevant, obsolet, „funny“ comments /**! * Returns the day of the month. *! * @return the day of the month. */! public int getDayOfMonth() {! return dayOfMonth;! }! ! /** Always return true. **/! public boolean isAvailable() {! !return false;! }! ! //Magic. Do not touch ! /* Added by Ana Cortés (4-4-2008) */!05.02.2013 11 www.consol.com
  • 12. Bad Comments /** ! * Dear maintainer:! * ! * Once you are done trying to optimize this routine,! * and have realized what a terrible mistake that was,! * please increment the following counter as a warning! * to the next guy:! * ! * total_hours_wasted_here = 42! **/!§  Commented-Out Code InputStreamResponse response = new InputStreamResponse();! response.setBody(formatter.getResultStream(), ft.getByteCount()); ! //  InputStream resultsStream = formatter.getResultStream(); ! //  StreamReader reader = new StreamReader(resultsStream); ! //  response.setContent(reader.read(formatter.getByteCount())); !05.02.2013 12 www.consol.com
  • 13. Good Comments§  Legal comments // Copyright (C) 2003 by Object Mentor, Inc. All rights reserved.
 // Released under the terms of the GNU General Public License version 2 or later. !§  Informative, clarification comments // format matched kk:mm:ss EEE, MMM dd, yyyy ! Pattern timeMatcher = Pattern.compile("d*:d*:d* w*, w* d*, d*"); !§  Amplification comments String listItemContent = match.group(3).trim(); ! // the trim is real important. It removes the starting ! // spaces that could cause the item to be recognized
 // as another list.
§  TODO comments§  Javadocs in Public APIs05.02.2013 13 www.consol.com
  • 14. Functions - Small!!public static String testableHtml( PageData pageData,booleanincludeSuiteSetup) throws Exception {
 WikiPage wikiPage = pageData.getWikiPage();! StringBuffer buffer = new StringBuffer();! if (pageData.hasAttribute("Test")) {! if (includeSuiteSetup) {! WikiPage suiteSetup =PageCrawlerImpl.getInheritedPage( SuiteResponder. SETUP_NAME, wikiPage);
 ! if (suiteSetup != null) {! WikiPagePath pagePath =suiteSetup.getPageCrawler().getFullPath(suiteSetup);! String pagePathName = PathParser.render(pagePath); ! buffer.append("!include -setup .").append(pagePathName).append("n");! } ! }! WikiPage setup = PageCrawlerImpl.getInheritedPage("SetUp",wikiPage);!... 40 lines more!05.02.2013 14 www.consol.com
  • 15. Functions - Small!!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(); !}!!!§  Better?!public static String renderPageWithSetupsAndTeardowns (PageData pageData,boolean isSuite) throws Exception { ! if (isTestPage(pageData)) ! includeSetupAndTeardownPages(pageData, isSuite); ! return pageData.getHtml(); !} ! !05.02.2013 www.consol.com! 15
  • 16. Command query separation§  What does it mean? public boolean set(String attribute, String value);!! if (set("username", "unclebob")) { ... } !
!§  Better? if (attributeExists("username")) { ! setAttribute("username", "unclebob"); ! } !05.02.2013 16 www.consol.com
  • 17. Don´t return null§  Throw exceptions or return special case object! List<Employee> employees = getEmployees(); ! if (employees != null) { ! for(Employee e : employees) { ! totalPay += e.getPay(); ! } ! } !!§  How to remove != null in the code? public List<Employee> getEmployees() { ! if( .. there are no employees .. ) ! return Collections.emptyList(); ! } !!!05.02.2013 17 www.consol.com
  • 18. Don´t return nullpublic void registerItem(Item item) { ! if (item != null) { ! ItemRegistry registry = persistentStore.getItemRegistry();! if (registry != null) { ! Item existing = registry.getItem(item.getID());
 if (existing.getBillingPeriod().hasRetailOwner()) { ! existing.register(item); ! } ! } ! } !} !!05.02.2013 18 www.consol.com
  • 19. Have no side effects§  Where is the side effect?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; !} !05.02.2013 19 www.consol.com
  • 20. Prefer exceptions to returning error codesif (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; !} !!!public enum error {! OK, INVALID, NO_SUCH, LOCKED, OUT_OF_RESOURCES;!}!05.02.2013 20 www.consol.com
  • 21. Prefer exceptions to returning error codes§  Better?public void delete(Page page) { ! try { ! !deletePageAndAllReferences(page); ! } ! catch (Exception e) {! logError(e); ! } !} !!private void deletePageAndAllReferences(Page page) throws Exception { ! deletePage(page);
 registry.deleteReference(page.getName()); ! configKeys.deleteKey(page.getKey()); !}!!private void logError(Exception e) {! logger.log(e.getMessage());!}!05.02.2013 21 www.consol.com!
  • 22. Keeping tests cleanpublic void testGetPageHierarchyAsXml() throws Exception { ! crawler.addPage(root, PathParser.parse("PageOne")); ! crawler.addPage(root, PathParser.parse("PageOne.ChildOne")); crawler.addPage(root, PathParser.parse("PageTwo")); ! request.setResource("root"); ! request.addInput("type", "pages");
 Responder responder = new SerializedPageResponder(); ! SimpleResponse response = ! (SimpleResponse) responder.makeResponse( new FitNesseContext(root), request); ! String xml = response.getContent(); ! assertEquals("text/xml", response.getContentType()); assertSubString("<name>PageOne</name>", xml); assertSubString("<name>PageTwo</name>", xml); assertSubString("<name>ChildOne</name>", xml); !} !!05.02.2013 22 www.consol.com
  • 23. Keeping tests clean§  Better?! public void testGetPageHierarchyAsXml() throws Exception { ! makePages("PageOne", "PageOne.ChildOne", "PageTwo");! ! submitRequest("root", "type:pages"); ! ! assertResponseIsXML(); ! assertResponseContains( ! "<name>PageOne</name>", "<name>PageTwo</name>", "<name>ChildOne</name>" ); ! } !!05.02.2013 23 www.consol.com
  • 24. Summary§  Read „Clean Code“ book.§  Be a little more careful with the code you write §  Write with the „audience“ in mind§  Follow the „Boy Scout Rule“ §  Leave the campground cleaner than you found it §  Use tools that help you cleaning up§  Write Clean Tests05.02.2013 24 www.consol.com
  • 25. Thank you! Danke! Gracias! !05.02.2013 25 www.consol.com