CFCamp 2012 - Great Coding Guidelines - V1.0

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

description

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

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

Page 1: CFCamp 2012 - Great Coding Guidelines - V1.0

Great Coding Guidelines

A beginner’s guide to write code for next generations

Aurélien Deleusière – CF Camp 2012

Page 2: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Who am I?

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 Railo

Monday October 15th 2012

Page 3: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Code for next generations

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…

Monday October 15th 2012

Page 4: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Think to the future

A working code is not enough… …it has to be robust and maintainable

Monday October 15th 2012

Page 5: CFCamp 2012 - Great Coding Guidelines - V1.0

JUST A POINT OF VIEWBefore digging into best practices…

©Aurélien Deleusière – CF Camp 2012Monday October 15th

2012

Page 6: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Readability or performances?

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?

Monday October 15th 2012

Page 7: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Mark’s CFML Myth BustersMonday October 15th

2012

Page 8: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Mark’s CFML Myth Busters

Monday October 15th 2012

Page 9: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Mark’s CFML Myth Busters

Monday October 15th 2012

Page 10: CFCamp 2012 - Great Coding Guidelines - V1.0

ART OF CODINGIn good hands,a few lines of CFML looks like poetry.

©Aurélien Deleusière – CF Camp 2012Monday October 15th

2012

Page 11: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Less is more

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 confident

Perfection is attained, not when no more can be added, but when no more can be removed.

Antoine de Saint Exupéry (1900 – 1944)

Monday October 15th 2012

Page 12: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Think before doing

Don’t rush on your keyboard!

Before writing, learn to think.What one understands, one expresses clearly.

Nicolas Boileau (1636-1711)

Monday October 15th 2012

Page 13: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Improve again and again

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!

Monday October 15th 2012

Page 14: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Other principles

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 test

Monday October 15th 2012

Page 15: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Languages mix

Don’t mix a logic across multiple language i.e. javascript, CFML and SQL

Keep the logic in one place

Monday October 15th 2012

Page 16: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Stealth coder

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 code

Monday October 15th 2012

Page 17: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Tags or script?

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.

Monday October 15th 2012

Page 18: CFCamp 2012 - Great Coding Guidelines - V1.0

YOUR CODE HAS TO TELL A STORYMake it readable!

©Aurélien Deleusière – CF Camp 2012Monday October 15th

2012

Page 19: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Coding style: be constant

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 choice

Monday October 15th 2012

Page 20: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Naming conventions

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; ...}

Monday October 15th 2012

Page 21: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Keep your code clean

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 refactored

Monday October 15th 2012

Page 22: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Comments

Do not overload your code with useless comment

<!--- init count to 0 ---><cfset count = 0 />

A comment is stronger when it is useful and frugal

application.proxy = {server = "",port = 80, // *MUST* be a numberuser = "",password = "”

};

Monday October 15th 2012

Page 23: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Comments

Avoid McDonald’s programming

// =======================================================// controllo esistenza fornitore su anagrafica q_fornitore = cfc_fornitori.GetAnagFornitore(idSocieta = my_idsocieta, idAnag = codFornitore, const = glb.const, dbprop = glb.dbprop); // =======================================================

// inserimento link fornitore linkfornitore = structNew(); linkfornitore.idSocieta = my_idsocieta;

//=======================================================if (q_fornitore.recordcount eq 0) {     // inseriemnto tan030anagfornitori     fornitore = structNew();      .....// =======================================================

Monday October 15th 2012

Page 24: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Variables scopping

Use every scope explicitly. Always Arguments, caller, query name, etc.

public Token function init(token) {variables.token = arguments.token;return this;

}

Monday October 15th 2012

Page 25: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Variables declaration

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");}

Monday October 15th 2012

Page 26: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Variables usage

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>

Monday October 15th 2012

Page 27: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Variables usage

Don’t use the pound sign where it is not needed

<cfset newColor = #oldColor# /><cfset newColor = "#oldColor#" />

But do instead:<cfset newColor = oldColor />

Monday October 15th 2012

Page 28: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Logic

if (isBlue == false) { ...}

Prefer:if (!isBlue) { ...}

Monday October 15th 2012

Page 29: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Logic

if (!isBlue) { doThis();

} else {doThat();

}

Prefer avoiding “if not else”:if (isBlue) {

doThat();} else {

doThis();}

Monday October 15th 2012

Page 30: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Logic

if (isBlue) { return true;

} else {return false;

}

Prefer:return isBlue;

Monday October 15th 2012

Page 31: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Logic

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?...}

Monday October 15th 2012

Page 32: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Always use brackets

if (token.equals("1234"))writeOutput("ok");

elsewriteOutput("ko");

Prefer:if (token.equals("1234")) {

writeOutput("ok");} else {

writeOutput("ko");}

Monday October 15th 2012

Page 33: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Exceptions

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 successsession.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>

Monday October 15th 2012

Page 34: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Decoupling

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>

Monday October 15th 2012

Page 35: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

About readability

Principle: no dynamic value into the condition of a loop

for (i = 1 ; i <= arrayLen(items) ; i++) {...

}

Monday October 15th 2012

Page 36: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

About readability

len = arrayLen(items);for (i = 1 ; i <= len ; i++) {

...}

Improvement: 0% to 5%

Monday October 15th 2012

Page 37: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

About readability

for (item in items) { // Railo and CF since 9.0.1...

}

Improvement: 10% to 15%

Monday October 15th 2012

Page 38: CFCamp 2012 - Great Coding Guidelines - V1.0

A REAL WORLD EXAMPLEWe learn more from our mistakes

©Aurélien Deleusière – CF Camp 2012Monday October 15th

2012

Page 39: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

RequirementsMonday October 15th

2012

Control birth date: 60 days minimum Must be right with the age entered (previous

screen)

Page 40: CFCamp 2012 - Great Coding Guidelines - V1.0

Original code

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; }}

}

Monday October 15th 2012

©Aurélien Deleusière – CF Camp 2012

Page 41: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Rewriting step 1

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;}

Monday October 15th 2012

Page 42: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Rewriting step 2

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;}

Monday October 15th 2012

Page 43: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Rewriting step 3

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;}

Monday October 15th 2012

Page 44: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Final code

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;}

Monday October 15th 2012

Page 45: CFCamp 2012 - Great Coding Guidelines - V1.0

©Aurélien Deleusière – CF Camp 2012

Final code

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)};

Monday October 15th 2012

Page 46: CFCamp 2012 - Great Coding Guidelines - V1.0
Page 47: CFCamp 2012 - Great Coding Guidelines - V1.0

Thank you! Vielen Dank! Merci !@adeleusiere • aurelien.deleusiere.fr • cfml-france.com