State of the art
There are many standards, even for a single programming language. Almost none of them will explain why they are that way (to my knowledge), and I wish they did. I personally adopted the Java conventions for a while, after the Pascal one and after the C/C++ one.
In the end, the goal of a standard/convention is the same:
(...) improve the readability of the software, allowing engineers to understand new code more quickly and thoroughly. (Oracle)I would add that any code should be like any good literature:
the right words in the the right amount to express something, no more, no less.
I learned a long time ago that one should not name its variables using its type. It's old school, because that's what *they* used to do back then. My theory is that using the type in the name helped engineers understand what kind of data type they were dealing with for the variable they were dealing with. IDEs were not as good as nowadays. However, it was redundant, because I'd understand the code just as much whether it's "int16Balance" or "int32Balance", it's a "balance" anyway.
Yukihiro Matsumoto (chief designer of the Ruby programming language) wrote in Beautiful Code that there are 4 elements to consider when writing code:
- Brevity
- Familiarity
- Simplicity
- The last one being the Balance between all of the above
We try to enforce our standard with code reviews (to teach) and plugins (to automatically validate).
Tripfilms Coding Standard
We basically follow the Java Conventions, with a couple of exceptions.
Formatting
We insist on the open braces being on the same line (at least I do), because on a new line, it becomes extraneous: when a line starts with an "if" or a "while" or a "for" etc., most of the time what follows is a block, so no need to add the "{" next line to only repeat that it's a block.
We like chaining too, on multiple lines and if the name of the methods are judiciously chosen, it reads (almost) like Shakespeare:
new SearchParameters()
.from(1)
.to(10)
.withQuery("category:ThingsToDo")
.withFacet("destination")
.sortOn("name");
In a very old fashioned way, the same code would look like this:
SearchParameters oParameters = new SearchParameters();To us, the former version is a better literature than the latter.
oParameters.setFrom(1);
oParameters.setTo(10);
oParameters.setQuery("category:ThingsToDo");
oParameters.addFacet(new Facet("destination"));
oParameters.setSort(new Sort("name"));
Programming Practices
We forbid what I call exception-oriented code. In Java, Exceptions are expensive, so the least we use them, the more stable the software will be. For example, validating user input should not throw exceptions.
Oh and no "catch and do nothing": log at least.
Naming
At Tripfilms, we went a bit further than the simple Java Conventions. To help engineers understand more quickly and thoroughly, we use a prefix for variables based on their scope:
- Members: m
- Parameters: p
- Local: o
- For single character variables (e.g. i, j, etc.) no need for a prefix
Example:
1. public class HelloWorld {
2. private MyBO mMyBO;
3.
4. public void sayHello(String pName) {
5. String oGreetings = mMyBO.hi(pName.length())
6. + " " + pName + "!";
7. System.out.println(oGreetings);
8. }
9. ...
10. }
Here's another example, same code but one with conventions (#1) and one without (#2):
1. User oUser = mDAO.load(pForm.getId(), oFetches.toArray())Now let's say we get a NullPointerException at that line of code.
2. User user = dao.load(form.getId(), fetches.toArray()
Without knowing anything from the application besides the naming conventions, I can say with #1:
- mDAO is a class member. If before getting to that line, some other part of the software was using that member (say another page of a website), it's then unlikely that the NullPointerException is due to the fact that mDAO is null (unlikely, but not impossible). The quick check here is to see if the class containing that line of code has been properly setup.
- pForm is a parameter of the function this line of code is from. It's more likely a culprit, but when I get to the source code, I can check quickly if anything was already using it before reaching that line.
- oFetches is a local variable. This one is even more likely the culprit (based on my experience) so that would be the first thing I'll look into when getting to the source code: making sure that this variable was properly assigned.
With practice, all that mental investigation happens in a split second.
With #2, there's absolutely nothing I can deduct from that line, so I'll just have to get to the source code and just delve into it.
Footnotes
Some conventions use underscore ("_") for some variables (e.g. member variables in Google C++ Standards[3]). I personally dislike this practice as it's not "natural" and it results in more keys pressed than the convention specified here (need to press Shift to make an underscore).
How many local, member and parameter variables have you typed so far? How many more will you type in your career? I did the math for myself, I even tried that practice for a while: it's faster for me to stick with letters for prefix when typing variable names.
Resources
[1] C# Coding Conventions
[2] GNU Coding Standards
[3] Google C++ Style Guide
[4] Game Coding Complete v4
No comments:
Post a Comment