What Workplace Coding Practices Do You Use?
Agent_9191 asks: "Recently I've been promoted to what essentially amounts to a project lead role for every project we do, in house. Since my company has run for the past 35+ years with no form of central IT department, there has been no standards put into place for developers to abide by. One of my tasks is to set up standards in how projects will be implemented and produced. Right now I'm more concerned about trying to set up coding standards, so that any developer can jump into any part of a project and be able to figure out what's going on, without wasting a couple hours just to figure out the code. I've come across some documents in this area from a few sources (of course can't remember them off the top of my head). What practices/standards do you use in your workplace?"
Tell them to use comments in code, and be sure that they make them good comments.
I don't preview or spellcheck.
Has several excellent articles on the subject This is about as good of a starting place as any.
SJW: a person who perceives an injustice, and while correcting it, commits a greater injustice.
If you really are starting from ground zero, I'd suggest setting up a repository such as SVN as a good first step. Couple this with a good template to set up standard locations for documentation directories alongside the code trunk and branches (and any other resources your projects requires (images, sound other media). Make sure everyone uses the repo - even if you have to spend a day leading people through it - you'll save time later. This also ensures your projects are backed up (so long as everyone checks in at the end of the day at least), and screwups - such as deleting the wrong directories and forgetting about it for weeks can be reversed.
Obviously there are other issues such as naming conventions, useful comments etc, which are often neglected in small projects, but become more important as more people work together without wars breaking out!
Find out your teams individual strengths and preferences - there's no point trying to hammer everyone into the same mould - some people will naturally gravitate toward, and excel at certain tasks. It's important for efficiency and general happiness that this is taken into account when allocating resources to a project.
Code, Hardware, stuff like that.
In my job as a web developer in a healthcare system, I'm all about evolutionary prototyping and other interative methods. There's a handful of big projects where we take a more traditional waterfall approach, but even then it's highly modified.
It's nearly impossible for me to get final specifications from a user until they've actually seen something. Paper is okay in a pinch, but a semi-functioning web application is worth a thousand meetings.
I like to think of it as "don't ask, don't tell" :D
got sig?
Unless you are dealing with trivial projects it will take more than a couple of hours to figure out the code. Even the best documented open source and commercial projects take a few days to figure out.
At every inspection; and of course example code for everyone to mimic the coding style.
And good unit test drivers.
Awesome commentary (both at the top of a package outlining the entire low-level design and at the algorithm level) goes without saying.
Oh yeah, and run spell on your code. I mean, really!
In the future, I would want to not be isolated from my friends in the Space Station.
That is a pipedream. Any project of significant size will require some immersion before a new proj member can get his hands around the particular bit he's trying code/solve.
Standards can be good, but they're not magical. Unless you're trying to generate a group of little robots, everyone has a slightly different style.
I'm all self-taught, so I have my own style which others tell me is impossible to make heads or tails of. The standard is: the boss promises stuff to our clients, and I have to whip it out [snicker] as fast as possible. Doesn't leave much time to make easy on those who would come after me. I jokingly call the mess of code I have to make JOB SECURITY.
"You know you're narcissistic when you quote yourself in your sigs." -- PRoPAiN!
GetOuttaMySpace - The Anti-Social Network
My suggestion is get someone who has done this in a structured and successful environment. Otherwise developers will roll you over and your projects will be late, over budget and buggy.
I have seen it so many times where an internal inexperienced person jumps in the saddle without mentorship and guidance in the areas of software development (NT or UNIX) and systems management not native to the environment. And I have seen how long companies suffer with the problems created by this and how much it costs companies in the end. It makes a $1000 per hour consultant look cheap.
A good example is code management. Very few IT shops have it. Why? No one wants to know who checked in the buggy code! But few developers want such tools, especially the microwave generation. But at least when your caffeine isn't good enough and they move on you will know where the source code is.
Sounds simple? Not really, there are hundreds of issues like the one above. And it can't be taught quickly.
So get a consultant for 6 to 12 months that has done this, listen and learn and you will be off to a fast start.
on this particular subject. i believe code complete 2 came out "reasonably recently". that said, were this my task, i'd say the following:
1) document things thoroughly using a tool like doxygen. there is no excuse for interfaces not to be thoroughly documented
2) adopt a standard naming convention. in java, this is easy -- just use the default. in other languages, you'll probably have to make your own up.
3) pick an indentation style. it really doesn't matter which since tools like indent can convert between them almost painlessly. all code that goes into the repository is run through indent to put it into a standard format
4) require that code compile cleanly with no warnings at the most anal retentive compiler settings before it can be checked in unless there are good reasons to ignore the compiler warnings
5) average devs are only able to commit to the "head" fork (or equivalent in your sccs). the code is not committed to the "real" fork until it passes whatever tests you have
6) incorporate tools like valgrind into your testing cycle --- they should come back largely clean. if they don't, things need to be fixed unless there's a really good reason not to.
7) people who check in code which breaks cvs or, upon a code review, are found to not sufficiently adhere to your guidelines owe their dev group donuts.
Yeah, standards are great.....we've got lots of them :-)
-Chris
--an unbreakable toy is useful for breaking other toys--
- Get a development database, a testing database and production database. Yes, you need all three.
- Write a few docs explaining each system. Make these are detailed as you possibly can. (This will save you weeks in the long term)
- Use software revision control. CVS, VSS, whatever, use one.
- Use a bug tracker. BugZilla, Jira, CityDesk, whatever, use one.
- Use whatever coding standards the language reckons you should. If java, use sun's standards. If microsoft, use their standards.
- Write automated unit tests. I don't care if you're not an agile or XP developer, write unit tests. Check out Junit, or Nunit, or just write your own.
- Setup some code so that you can check out ALL code from the source code repository and compile it by ONE COMMAND. Eg, "make" or "ant" or "maven" or whatever. This will take time but is worth it.
- Have a naming standard for database tables. This will make your life SOOOO much easier.
- Read thedailywtf.com and don't do anything that is posted there.
- Write specs for your new developers. Please write specs for your new developers. Don't just say to them 'fix this up'.
- Make sure code isn't hard-coded to a particular directory. Everyone does this. Fix it. (Might be part of step 7)
- Create your own standard config files.
- Have code reviewed by peers. Don't be a bastard but be nice when picking on people's code.
- As mentioned, comment your code but use the language standard. Java - javadocs, Perl - perldocs, etc. These are cool, but don't get too carried away. Nothing can replace a good spec.
- Ignore what most people say on Slashdot. (Except for me, of course).
That'll keep you busy for a couple of months! Doing thiswill make you well on the way to having a pretty high level of coding quality. Most companies don't do all of them. Good luck.The moral of the story?
A. You are not the font of wisdom. If very lucky, you are the point of the pen. Rule carefully.
B. Don't make standards based on what you learned in school. Base them on what you learned in real life.
C. If an Old Fart tells you that one of your edicts is stupid, don't assume that they're resistant to change just for the sake of being crotchety. Maybe they learned something useful over all those years and all those lines of code.
I think the most important policy is to slap the guy that says, "I like tabs more than spaces" or "I don't like the way you indent" or "I hate the way you put spaces around ('s".
Honestly? These people have too much free time. People use a variety of conventions and I've seen pretty much all of them. As a senior developer, I just take everyone's idiosyncracies in stride, even when they name variables retarded things like: n, vt, pkq, and rsptln.
If I can deduce what they are doing easily, it is no problem. If I cannot, I make them explain it. If they are not around anymore, problem solved. I rewrite or have their stuff rewritten in a good way, since the stuff was 99% likely to be utter crap anyway, and move on without a moments hesitation.
I've worked on a lot of large codebases and I've never encountered this idea of, OMG this code is so archaic that I cannot possibly decipher this person's intent--and believe me, I've worked on some crazy ancient crap. My obligatory developer arrogrance leads me to state that people that cannot figure out code because of coding conventions are weak developers. Anyone that has slogged through the convoluted "efficiency" of Knuth or the a,b,c,i,j,k madness of Wirth can figure shit out.
So anyway, if you have the authority and your people are actually willing to go along with a standard without a huge hullabaloo, then just pick any standard (you'll get way more mileage from just sticking to a consistent convention no matter what it is). If people are going to make a big deal of it and it is difficult to enforce, just deal with it individually and tell people to write sane things. Their coworkers will provide quite good feedback if they are producing shit, and that's where you really need to step into your lead role and work out a resolution.
One of your best tools for a standard is to create automation to enforce it. Get yourself some prettyprint scripts that you have run on all source that is checked in--in fact, get your developers the same tool so they can run it on what they check out to print it the way they like it. (Of course, you only want to check the source in with the standard pretty printing or diffs become atrocious, but that's technical stuff for a different discussion.)
Bottom line is that whatever you can automate in the way of conventions is a win because then it's completely automatic, difficult to bicker about (two coworkers can't very well bicker at each other when it's the prettyprinter's fault, so they can only come to you and you have authority to resolve the issue right quick, whereas they could just engage each other in an endlessly unproductive slugfest if they are coding by the convention of their opinion), and if people want a change it goes through you and you have a strong argument for--"if it isn't broke, don't fix it".
Kind of a ramble, but after many years this is my take on standards. Use a convention if it is convenient. If not, play it a bit more loose, but be firm on snuffing out those annoying neverending debate situations.
That said, one factor that is relevant is the type of work you are doing. I'm assuming from what you said that you have some flexibility to structure as you like. If for instance you were subject to government or other agency auditing (my current company is), then the loose method is not going to fly, but on the other hand, you would probably already know what conventions you needed becaus
enum is your friend!
...
;-(
enum {LOAD_DATA, SAVE_DATA, DESTROY_DATA}
Paul B.
P.S. And of course my all-caps enum values were considered too lame by lameness filter...
The best description I've ever come up with for the Geek mindset is this: a Geek can hold a complex structure in her head and manipulate it with ease. A History Geek can hold the structure of a historical event and see motivations and causes from every angle; a Carpentry Geek can plan an entire piece of woodwork and see every cut and join vividly; a Programming Geek can hold a program's structure and its data and event flows and manipulate it as an idea.
Someone commented that the difference between Microsoft and Google is that Microsoft programmers are holding concepts the size of "If...Then...Else" and Google programmers are holding concepts the size of Bayesian filtering; thus, Google's Geeks are better at making big, coherent plans without getting lost in the details. It's not 100% true across the board, but it's an insight.
As a Project Manager, then, your job is to:
1. Allow your Geeks to transfer the concepts from the screen/page/whiteboard into their heads; and
2. Allow your Geeks to hold those ideas easily once they've got them.
Step 1 is a bandwidth issue: make the "inputs" more efficient by, for example, giving all of them dual-head monitors and high speed printers, so they can get lots of code into a usable format for reading (some of us prefer printouts; others just need vi/Emacs and a flicker-free monitor). Step 2 is a quality issue: Geeks who have to hide in headphones or run away to the park to read because of ringing phones and nagging managers are NOT going to be able to do their job.
And with any data pipe, throughput is more a function of time rather than pressure. So your dream of getting your programmers up to speed in minimum time really is -- pardon the pun -- a pipe dream. They won't be any use to you if they don't have the time to learn the systems they're working on.
I have discovered a truly remarkable
Its for wussies!
-USe tons and tons of goto statements.
-Make sure you use particular letters capped for variables of different types to make them more confusing for the losers who can't read the code and remember what each one was.
- always make calls by reference using pointers as arguments. Don't use call by values.
- Hell user other pointers that use other pointers to make things more interesting. Reassign them all over the place
- Never use a three tier model when developing client/server apps. This only creates redundancy and gets in the way of solving the problem.
- When linking to a database always use vendor specific extensions and avoid a database layer using something like odbc. It makes use of the advanced feature set by the particular RDBMS.
- Be a man! Show how much you know perl. Alot of one linners can save tons of time with exotic line switches
Oh last... make tons of money and gain job security because no one in Earth will be able to understand or work on your projects after doing all of these things. Enjoy
http://saveie6.com/
without wasting a couple hours just to figure out the code.
A couple hours???
Look, no offense, but you either only deal in "toy" code, or you have such high expectation that you will fail, and quite spectacularly.
A new coder, even an experienced one, takes days or even weeks after coming into an existing project before he can contribute anything but the most trivial of changes. For a truly massive project, or one that requires intimate domain-specific knowledge in a niche industry, extend that to months.
If you can find a way to get an unfamiliar newcomer up to speed on any "real" project in a matter of hours, consider your talents wasted in your current position.
In addition to some of the suggestions made so far I would add a good automatic regression-test system which runs every night, and reports problems (build failures or result diffs). I've made mine so they "find the guilty" (whoever committed code since the last good regresstion test).
I recently put together a list of Fundamental Coding Truths after musing about this topic and why it was so hard to plan software development:
1. Software is not at its core a collection of a few clever algorithms.
Rather, it is primarily (in the ways that matter) a huge collection of arbitrary
choices and random implementation details.
The algorithms that consititute the mathematical/logical basis of a piece of software
are an important, but very small (eg: 1%) and relatively very simple part
of the overall code.
2. Code complexity is pretty much exclusively determined by the (combinatorial)
number of interactions between pieces. Each interaction requires at least one decision
and usually many more.
3. Because of #1 and #2, deep, intimate familiarity with the code (this vast
collection of implementation details) is only ever fully knowable to the original
author(s) who made these uncountably many, mostly arbitrary decisions.
(Familiarity by secondary authors/maintainers comes primarily from
re-writting sections of code.)
4. Because of #3, programmers are not interchangeable. The efficiency with
which a person can navigate the code, implement or even imagine changes
is almost entirely determined by how familiar they are with these many, many small
details. The ratio of efficiencies between a primary author and another
equally talented coder is very large (eg: 100). Because of this, the original
authors of a section of code are usually the only ones who are ever able to efficiently
modify or restructure it. This becomes rapidly more true as the the size and
complexity of the code increases.
5. Because of the complexity of code (the number of interactions and interdependencies),
debugging and maintenance constitutes the vast majority (eg: 99.9%) of the work
required by a piece of software over its life.
6. Because of the complexity of code (number of interactions between components), it is
very hard, if not impossible, to predict with any accuracy what will be involved in implementing
a given change. Even for original authors, unintented side effects are almost inevitable, and
the primary determinant of the length and difficulty of a task lies in finding and rectifying
unintented consequences or unforseen interactions. Because of this, the uncertainty in the time
it will take to execute a change is very large.
(eg: 10x range in 95% confidence limit of time estimate, say 1 day-2weeks).
7. Because of the complexity of code, bugs are an inevitable byproduct of writing code. It is hard
to predict how long it will take to find and repair bugs as that depends on how many side effects are
involved, which is not known until the repair is done and "fully tested". The only way to avoid bugs
completely is to not write code. There are things that can minimize bugs or speed up finding/fixing
them, but they will always exist.
Perhaps someone broke in and fixed the code.
how to invest, a novice's guide
C# - The C# Coding Style Guide, Mike Krueger(SharpDevelop). This is probably the most widely used one (Novell). It largely agrees with Microsoft's internal coding standards, with a few exceptions. .Net Coding Standards, part of the SDK. This is not comprehensive though, like the C# doc mentioned above.
VB -
Version Control -
Server: Subversion + Apache
Client: Tortoise SVN (Excellent) [We also use Perforce, CVS, VSS(Commercial apps)]
Continuous Integration - Cruise Control.Net
Intranet, Knowledge Management - DotNetNuke (www.dotnetnuke.com)
Project Management - dotProject (PHP) (www.dotproject.com), MS Project
Unit Testing - NUnit (www.nunit.org)
Life is just a conviction.
Steve McConnell's Code Complete is an excellent source for coding standards and a good read for any developer. I don't agree with everything in the book but it is comprehensive. Ignore that it's published by Microsoft Press, it's a good one.
Snowden and Manning are heroes.
Read and apply the Pragmatic Programmer.
Hungarian notation has its (extremely limited) uses. The reality is that it turns code into garbage. Go ahead, read aloud the lines of code below.
// the old c style
if(cur == last) rec->tag = name;
// camel case
if(currentKey == lastEntry) Record->keyTag = userName;
// hungarian
if(iCurrentKey == iLastEntry) prRecord->m_pszKeyTag = pszUserName;
Now imagine discussing them with your coworker. Imagine thinking in your head "What should I do if prRecord->m_pszKeyTag is NULL?" Humans are good at symbolic manipulation. Giving something a name makes it easier to deal with. Giving something a label that cannot be easily manipulated in language (spoken or in your head) severely hampers the ability to think it through.
The argument for Hungarian is usually "but it lets you know what the variables are". This is the maintainance programmer argument. This argument rarely makes sense in reality, unless some very bad programming is involved. First of all, if you do not understand the current code you are about to modify, you should *not* be modifying it. If your maintainance programmer is just going to have a look at two lines of code, add a third in the middle, and hope for the best then you are truly fucked. He has obviously not understood the code enough to know what the consequences of the modification will be. The reality is, if your current logic unit is such a monstrosity that looking up the types of your variables is a burden, and your variable names are so poor that it is insufficient to infer at least a basic understanding of what is going on without having to resort to prepending types, you should probably step away from the keyboard, turn off your computer, and tell your boss that you had an epiphany and will be pursuing a career in French fry development.
If you want code that can be readily understood you need something other than coding conventions. Coding conventions only make the code all look the same. You can get almost all of the benefit (without most of the arguments) by saying only that each file must be written with the same coding convention throughout. The code will get prettier and prettier with tighter conventions and developers will waste less time reformatting each others code. But it won't do a thing to make your project more understandable.
For that you need an understandable design and the best advice I've ever seen for that is in Eric Evens' "Domain Driven Design" http://domaindrivendesign.org/. The advice there will work for both Agile and non-Agile projects and its core themes are pretty much unavoidable truths about how to write code for a project that is also written about the project: use language that comes from the projects domain, insulate code from each domain or sub-domain from the rest of the world, keep each method at the same level of abstraction (that's big) and make implicit concepts explicit, to name a few. The key is for your developers to consider themselves to be authors and to strive to keep each little piece of code they write on-topic. Not only will it be easier for new developers to come up to speed but the code will work a heck of a lot better too.
As someone with 20+ years of professional programming under my belt, a lot of it doing maintenance and enhancement of existing code, I'll say this: most of what's considered "coding standards" doesn't much matter. Indentation, brace positioning, type prefixes on variables, underlines vs. StudlyCaps, capitalization in general, most competent programmers can pick up on any variation quickly. The few things that count are more general:
replace a stupid name with a sensible name:
messages_processed++;
This actually makes sense without the comment.
I once came across a ~1400 line function of complex maths transformations with one comment
i++ /* increment i */
What's i? and more importantly why increment it?
More importantly: Don't be too clever.
It's when people try to get clever in their coding that it gets hard to read. And, quite frankly, that's the code that generally breaks most easily.
This sig has absolutely no significance and serves only to take up screen space and waste the time of the reader.
"I once came across a ~1400 line function"
This is so fucking wrong and wicked the programmer who did it should go straight to hell. I'm sure there's no functional coesion in there: most likely there are many disparate tasks that should be each in its own function and called from there. I'm sure there is a lot of cut-n-paste in there that should be each in its own function and called from there.
I'm sure you can guess where i'm willing to get to... more important than hungarian notation, comments or documentation in PDF format is abiding for these 2 simple rules: KISS -- keep it simple, stupid -- and DRY -- don't repeat yourself. Once you do it, coding and reading code is a lot easier.
So, my advice:
* Give meaningful names to important, global, business rules variables ( local variables like i or c are ok, since they are mostly irrelevant ) or functions/methods/procedures/subroutines
* Write short, highly coesive functions/methods/procedures/subroutines
* Stop the cut-n-paste madness! If you do it a lot, it's obvious the copied code if begging to be parametrized and be given a name. Programmers altering your original code will be thankful
* Write modular code, not a plain, huge, stupid monolithic wall of letters. Even in languages with no namespace support ( C/PHP etc ) a good naming convention for functions of a certain module/header can do wonders...
* and please: meaningful names don't mean phrase-like names like thisLocalVariableIsCool. Conciseness go a long way towards good readability...
I don't feel like it...