I work with a small team of developers – there’s about seven of us in total that do full-time development. Of that group, there’s only a few of us – about three – that I would call “serious” about coding – by which I mean would have heated and/or deep conversations about “good” code. Of those three, two of us typically feel about the same, and the third doesn’t really agree.
If it’s not already obvious by the wording of that last sentence, I’m in the two-person group. The two of us have pretty similar ideas on how to write good code. Here are some of the principles we try to follow:
YAGNI (You Ain’t Gonna Need It)
I heard a variant of this in college that went “Lazy programmers are good programmers”. The idea here is: don’t write code you don’t need. This obviously varies a bit depending on what you’re writing, but in general, just don’t create anything until you need it to exist. We work in a teeny team and all our development is for internal projects. It’s a giant waste of time to try to create a perfect solution that will fit everybody’s needs, especially when you don’t know what those needs are.
Don’t Reinvent the Wheel
If you run into a big, general problem, someone else has probably solved it, and has done a better job than you will. I don’t care how good you are, you’re not going to sit down one day and turn computer science on its head. You’re not going to sit down one afternoon and crank out a better solution than a several-hundred-man-hour open source project. So don’t think you’re right and they’re wrong because they don’t do something the exact way you want. Instead, just benefit from the hundreds of hours of work and expertise that has gone into creating something ahead of you.
We All Write Bad Code
Everyone has written crappy code at some point, so when someone calls you out on it, just accept it and move on. I have a hard time with this one myself, since my instinct is to fiercely defend any assault on my code as if you’re trying to eat my baby. But there have been plenty of times I go back and look at my code and say, “what was I thinking?!”
Be Open Minded
There’s always something new to learn as a developer – it’s why I love my job. There will always be a new technique, a new language, or a new style out there. It’s important not to get set in a particular at of doing things.
Now, it’s time for me to rag on person number 3…
I’ve gotten into arguments about code at work before. It hasn’t happened lately (mainly because I haven’t had to work with that particular person), but it still bugs me. After putting a lot of thought into it, I think I’ve settled on the fact that I’m a bit of a snob when it comes to code. Be warned, I’m about to do a lot of patting myself on the back.
Plenty of people can write code. Writing code to make a computer do things is not hard. It’s a science – there’s a good bit of learning, sure, but once you know the language, you can do all sorts of things.
I think what makes a good programmer is art. There’s a difference between getting the job done and writing good code. Good code is clean, simple, and elegant.
I code in C#. I absolutely love it. It’s a wonderful language, and anyone who thinks otherwise obviously hasn’t spent much time with it. However, a lot of the greatness behind C# is in the work Microsoft has done on the .NET framework to add tons of code to make my life easier.
LINQ
I think LINQ is God’s gift to programmers. It’s simple, it’s clean, it’s powerful, and it’s easy to understand. I do a lot of data analysis-style work. That means taking a bunch of data and processing it to get more data. Let’s take a simple example of calculating the average for a set of data points.
[csharp title=”Old-School”]
float total = 0;
foreach(float value in data)
{
total += value;
}
float average = total / data.Count;
[/csharp]
Now, that’s not complicated. Any programmer can read and understand that. It’s not technically wrong. However, I’d argue it’s not good, especially when you have this alternative:
[csharp title=”LINQ”]
data.Average();
[/csharp]
I’m fairly certain someone who is not a programmer can understand that. Why wouldn’t you use that if you had it at your disposal?
Now, that’s actually a LINQ extension method. I prefer the extension methods to actual LINQ syntax, but they’re both great. Actual LINQ syntax is a lot like SQL:
[csharp]
var points = from x in xValues
from y in yValues
select new Point(x, y);
[/csharp]
It’d be easy to wrap your “average” code in a simple static method in a utility class and use it wherever you wanted. The power in LINQ comes from being able to chain things together. For example:
[csharp]
var moreData = points.Where(p => p.y > 20).Select(p => p.x).Average();
[/csharp]
OK, we’ve gone back into programmer-only town. But if you know LINQ (or maybe just C#), you can see that means you’re taking the points where y is greater than 20, selecting their x values, and averaging them. Even without knowing what it all means, you can start to get an idea of what’s going on – you’ve got points, and where something is true, you’re selecting something, then averaging it. It’s a natural way to think about the data.
Extension Methods
C# has a feature called “extension methods”. As the name implies, these are methods that extend another object. These are extremely handy when you don’t control the object in question. For instance, say you want to add some functionality to an object created by Microsoft. With an extension method, you can add that functionality.
You could always write the method as a static method on a utility class:
[csharp]
Utility.DoSomething(myObject);
[/csharp]
This is fine, and gets the job done. But with a very minor change to the “DoSomething” method, you can also use it like so:
[csharp]
myObject.DoSomething();
[/csharp]
Of course, this may not always be appropriate, but I find it often produces more readable code. The other benefit is with IntelliSense, where once you’ve typed myObject., a list of what you can do appears.
I’ve heard it said you should use extension methods sparingly, and that’s absolutely true. Some things just don’t make sense as extension methods. However, I’ve found they often make my code look better and read better, and if you’re using LINQ, they can fit in with the LINQ methods beautifully.