CFCamp 2012 - Great Coding Guidelines - V1.0
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

CFCamp 2012 - Great Coding Guidelines - V1.0

on

  • 2,054 views

A beginner’s guide to write code for next generations

A beginner’s guide to write code for next generations
Aurélien Deleusière – CF Camp 2012

Statistics

Views

Total Views
2,054
Views on SlideShare
2,048
Embed Views
6

Actions

Likes
0
Downloads
26
Comments
0

3 Embeds 6

http://eventifier.co 3
http://ec2-54-243-189-159.compute-1.amazonaws.com 2
http://www.scoop.it 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

CFCamp 2012 - Great Coding Guidelines - V1.0 Presentation Transcript

  • 1. Great Coding GuidelinesA beginner’s guide to write code for next generations Aurélien Deleusière – CF Camp 2012
  • 2.  Based in Paris, France Software engineer specializing in web technologies, development, architecture and troubleshooting ColdFusion since 1998 Founder of Aurel&Co Involved into the French community And, yes, I‟m supporting RailoWho am I?©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 3.  Think to the next generations of developers Think to yourself when you will have to get back to your code later Think to your colleagues… it‟s your reputation…Code for next generations©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 4.  A working code is not enough… …it has to be robust and maintainableThink to the future©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 5. JUST A POINT OF VIEWBefore digging into best practices…©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 6.  Both of course! But I would prefer a clean code than a fast code Use performance mechanisms when possible like mainly caching Always understand what you‟re doing:  may this array can be huge one day?Readability or performances?©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 7. Mark‟s CFML Myth Busters©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 8. Mark‟s CFML Myth Busters©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 9. Mark‟s CFML Myth Busters©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 10. ART OF CODINGIn good hands,a few lines of CFML looks like poetry.©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 11.  Keep your code as simple as possible Use small functions, small files, small number of arguments, small names… …small is beautiful Break down complex and large things to simple and little tasks Once it works – and is tested - close your eyes and be confidentPerfection is attained, not when no more can beadded, but when no more can be removed. Antoine de Saint Exupéry (1900 – 1944)Less is more©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 12.  Don‟t rush on your keyboard!Before writing, learn to think.What one understands, one expresses clearly. Nicolas Boileau (1636-1711)Think before doing©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 13.  Improve your code each time you get back on it  « Leave code better than you found it » Anticipate: This function could do more… Consolidate: I‟ve already seen this somewhere… Do not duplicate code! But in any case: TEST, TEST and TEST!Improve again and again©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 14.  Truth is always in source code Be curious Be confident  Do not hesitate to refactor, the only reason that should stop you is how difficult it is to testOther principles©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 15.  Don‟t mix a logic across multiple language  i.e. javascript, CFML and SQL Keep the logic in one placeLanguages mix©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 16.  It‟s not about which guidelines…  …but have guidelines When you go into a code is not yours, enter in stealth mode, mimic the style in place:  Make impossible to identify you when others read your codeStealth coder©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 17.  Tags fit well with views Script with business code You can only use tags, it‟s your choice. You can only use scripts, it‟s your choice…  …but never do that. Never.Tags or script?©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 18. YOUR CODE HAS TOTELL A STORYMake it readable!©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 19.  Do or do not but do always the same way:  to indent your code  „ or “  ending slash for unary tags <cfabort />  spaces <cfset count = 0 />  void lines  … One style by language is a good choiceCoding style: be constant©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 20.  Clear name with meaning Boolean should begins with is or has (isBlue) About case:  Only object names should begin with an upper case  Separate words with an upper case, avoid using the old fashion “_”public void function onApplicationStart() { application.physicalRoot = expandPath("/"); application.env = new model.utils.Env(cgi.server_name); application.sanitizer = new model.utils.Sanitizer(); application.cfTags = new model.utils.CFTags(); application.debug = false; ...}Naming conventions©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 21.  Don‟t leave garbage into your code<cfif 1 EQ 2>...</cfif> Don‟t comment code, remove it You identify a portion to improve? use Eclipse tasks://TODO: This block needs to be refactoredKeep your code clean©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 22.  Do not overload your code with useless comment<!--- init count to 0 ---><cfset count = 0 /> A comment is stronger when it is useful and frugalapplication.proxy = { server = "", port = 80, // *MUST* be a number user = "", password = "”};Comments©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 23.  Avoid McDonald‟s programming// =======================================================// controllo esistenza fornitore su anagraficaq_fornitore = cfc_fornitori.GetAnagFornitore(idSocieta =my_idsocieta, idAnag = codFornitore, const = glb.const, dbprop = glb.dbprop);// =======================================================// inserimento link fornitorelinkfornitore = structNew();linkfornitore.idSocieta = my_idsocieta;//=======================================================if (q_fornitore.recordcount eq 0) { // inseriemnto tan030anagfornitori fornitore = structNew(); .....// =======================================================Comments©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 24.  Use every scope explicitly. Always  Arguments, caller, query name, etc.public Token function init(token) { variables.token = arguments.token; return this;}Variables scopping©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 25.  Declare a variable where it‟s used… avoid the old fashion of all the declaration on top (legacy from var scoping up to CF8)public string function generate() { var i = 0; var token = ""; for (; i <= 32 ; i++) token &= chr(randRange(65, 90)); return hash(token, "MD5");}public string function generate2() { var token = ""; for (var i = 0 ; i <= 32 ; i++) { token &= chr(randRange(65, 90)); } return hash(token, "MD5");}Variables declaration©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 26.  Don‟t use Magic Numbers. Never.<cfswitch expression="#quoteRow.groupID#"> <cfcase value="12"> <cfset quoteRow[isAnnual][1] = "yes" /> </cfcase> <cfcase value="13"> <cfset quoteRow[isAnnual][1] = "yes" /> </cfcase> <cfcase value="24"> <cfset quoteRow[isAnnual][1] = "yes" /> </cfcase> <cfcase value="25"> <cfset quoteRow[isAnnual][1] = "no" /> </cfcase></cfswitch>Variables usage©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 27.  Don‟t use the pound sign where it is not needed<cfset newColor = #oldColor# /><cfset newColor = "#oldColor#" /> But do instead:<cfset newColor = oldColor />Variables usage©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 28. if (isBlue == false) {...}Prefer:if (!isBlue) {...}Logic©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 29. if (!isBlue) { doThis();} else { doThat();}Prefer avoiding “if not else”:if (isBlue) { doThat();} else { doThis();}Logic©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 30. if (isBlue) { return true;} else { return false;}Prefer:return isBlue;Logic©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 31.  Parenthesis:if (isBlue || isRed && isSquare) {...}if (isBlue || (isRed && isSquare)) {...}return variables.token == arguments.token;return (variables.token == arguments.token); Order of variablesif ("blue" == color) { //don‟t, use EQ?...}Logic©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 32. if (token.equals("1234")) writeOutput("ok");else writeOutput("ko");Prefer:if (token.equals("1234")) { writeOutput("ok");} else { writeOutput("ko");}Always use brackets©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 33.  Exceptions allow you to focus on the useful code<cffunction name="login" access="public" returnType="boolean" output="false"> <cfargument name="username" type="string" required="yes" /> <cfargument name="hash" type="string" required="yes" /> <cfscript> try { var user = request.object.new("User").init(arguments.username); var hashServer = hash(session.token & user.getPassword(), "MD5"); if (hashServer == arguments.hash) { //connection success session.user = user; user.lastLogon(username); return true; } var debug = "username=#user.getUsername()#<br>password=#user.getPassword()#<br>"; } catch (objectNotExistsException e) { var debug = "user not exists exception (#arguments.username#/#arguments.hash#)"; } catch (connectionFailedException e) { var debug = e.message & "<br>" & e.detail; } </cfscript> <cfthrow type="loginFailedException” message="...” detail="#debug#" /></cffunction>Exceptions©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 34.  Don‟t make entities dependent on each others<cfset colors = "blue,red,green,yellow" /><cfloop from="1" to="10" index="i"> <cfinclude template="sometemplate.cfm"></cfloop><!--- sometemplate.cfm ---><cfset i = 0><cfloop list="#colors#" index="lst"> <cfset i++ /> ...</cfloop>Decoupling©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 35. Principle: no dynamic value into the condition of a loopfor (i = 1 ; i <= arrayLen(items) ; i++) { ...}About readability©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 36. len = arrayLen(items);for (i = 1 ; i <= len ; i++) { ...}Improvement: 0% to 5%About readability©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 37. for (item in items) { // Railo and CF since 9.0.1 ...}Improvement: 10% to 15%About readability©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 38. A REAL WORLDEXAMPLEWe learn more from our mistakes©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 39.  Control birth date:  60 days minimum  Must be right with the age entered (previous screen)Requirements©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 40. function isBirthDateValid(value,element) { var tmp = value.split("/"); if (tmp.length != 3) { return false; } else { var month = tmp[1]-1; var year = tmp[2]; var day = tmp[0]; if (isValidDate(month,day,year) != true) { return false; } else { return true; } }}Original code©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 41. function isBirthDateValid(value,element) { var tmp = value.split("/"); if (tmp.length == 3) { var month = tmp[1]-1; var year = tmp[2]; var day = tmp[0]; if (isValidDate(month,day,year) != true) { return false; } else { return true; } } return false;}Rewriting step 1©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 42. function isBirthDateValid(value,element) { var tmp = value.split("/"); if (tmp.length == 3) { var month = tmp[1]-1; var year = tmp[0]; var day = tmp[2]; return isValidDate(month,day,year); } return false;}Rewriting step 2©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 43. function isBirthDateValid(value, element) { var tmp = value.split("/"); if (tmp.length == 3) { var day = tmp[0]; var month = tmp[1] - 1; //month start at 0 var year = tmp[2]; return isValidDate(month, day, year); } return false;}Rewriting step 3©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 44. function isBirthDateValid(value, element) { try { var birthDate = $.datepicker.parseDate(dd/mm/yy, value); if (birthDate.getAgeInDays() >= 60) { // we retrieve the current id from ”birthDate_X” // to check the age against "age_X" var id = element.id.split(_).pop(); if (birthDate.getAge() == $(#age_ + id).val()) { return true; } } } catch (e) {} return false;}Final code©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 45. Date.prototype.getAge = function() { var today = new Date(); var age = today.getFullYear() - this.getFullYear(); var monthes = today.getMonth() - this.getMonth(); var days = today.getDate() - this.getDate(); if (month < 0 || (monthes == 0 && days < 0)) { return age - 1; } else { return age; }};Date.prototype.getAgeInDays = function() { var today = new Date(); return Math.floor((today - this) / 86400000); //ms to days (24*60*60*1000)};Final code©Aurélien Deleusière – CF Camp 2012 Monday October 15th 2012
  • 46. Thank you! Vielen Dank! Merci !@adeleusiere • aurelien.deleusiere.fr • cfml-france.com