“One of the differences between a great programmer and a bad programmer is that a great programmer adds logging and tools that make it easy to debug the program when things fail.” [reference below]
I’m sure you’ve experienced a good share of mystery/quiet/business-as-usual failures.
Wouldn’t it be nice to have code that is smart to detect error conditions and make it obvious?
There are many ways of doing the communication. Some are trivial and easy to do. Some require extra thinking. Some require that extra step — step which is not in acceptance criteria.
Logging is one. It falls under the “trivial and easy to do” category. I feel we’re not utilizing it to its full potential. I’ve seen many instances where error conditions are not visible in logs. When we debug issues everything works as expected. So it seems… Then what? We need to keep digging. We’ve got to turn into code and look for clues. It’s time consuming. It’s frustrating. Wouldn’t it be better if we got a clue from the log?
“When the program works as expected, there is often no difference in the quality of the logging. However, as soon as the program fails, or you get the wrong result, you can almost immediately tell the good programmers from the bad.” [same reference]
Exactly. Logging gets a bad rap. But it’s invaluable in situations like those. It’s a great lead in finding the underlying cause of the issue.
So think about those error conditions. Check that the object you’re working on is in a “correct” state and if not add a warning message. Those warning and debug statements serve as an excellent documentation tool! Think of them as live comments.
Most of our loggers are accessible via JMX. That means no restart is required to change a log level. Very convenient!
There is really no reason why all of us should not be utilizing logging.
Logging is just one way. There are other ways. Think of stats/counters/jmx/dashboards. These require that extra effort and thought but are critical in communicating the health of the system. And there are cases where logging might be excessive when we expect an error to happen frequently. It’d be better to 1) output a message about a fail rate once a minute or so and 2) have stats accessible via jmx/dashboard. That allows us to see if the feature we built is working as expected, but also monitor performance/usage/etc.
I’m sure there are other ways.
But the bottom line is that we shouldn’t just be asking “does it work?” but how am I going to debug it things don’t work? How is it going to respond to error conditions? How am I going to validate that it actually does work?
If you learn to write debuggable code there are a few things that will happen.
1) You will become a better programmer
You’ll start thinking of the end result. You’ll cover the edge cases and “share” those unexpected values/conditions. You’ll be delivering smarter and friendlier code.
2) You’ll reap the benefits when debugging issues
It’ll happen. It’ll happen sooner than you think. And you’ll be thankful that you or somebody else took the extra care and added those debug statements/stats/etc.
Writing debuggable code takes effort and skill. But those extra steps, that extra effort is what distinguishes the good from the best.
Great Programmers Write Debuggable Code
Almost all of us know the GoF patterns. Perhaps not all of the patterns. I forget them from time to time, but with more experience, I remember more and more. (I keep forgetting what a Memento is. )
As important as they are, I think there are other, perhaps more important patterns and principles that I follow. Some of them are “in my head” when I code. Some of them are there and I just follow them without naming.
They are fundamental theorems/patterns/principles of programming.
Good idea to review them.
Good idea to write about them.
Good idea to revisit them.
Don’t you think?
Languages and trends pass by. Principles and how we approach our programming tasks stays with us. Forever.
Once we have solid principles in place, we’re able to reuse it from language to language. Deepening and improving that knowlege has the highest return, I feel.
So I’d like to revisit SOLID principles; GRASP patterns. They’re at the heart of programming. Close to my programming heart, at least. More to follow.
While looking at the top weekly links on dzone (good way to see what are the important things that happened), I came across a very intriguing entry: The Top 10 Attributes of a Great Programmer by Steve Riley.
These always “get me,” but a lot of times they end up being just a quick browse. This one is different. Though the attributes are similar to what I”ve seen before (see entries in Craftsmanship category), they’re good. And it’s always good to re-read them.
Here are the top 10 form the blog. Read the whole post as the author gives his own explanations. My thoughts are below.
- Being a great problem solver.
- Being driven and lazy at the same time.
- Ability to understand other people’s code
- Having a passion for programming
- Loving learning for the sake of learning
- Being good at math
- Having good communications skills
- Strong debating skills
- Extreme optimism
- Extreme pessimism
Being a good problem solver? Of course! Great programmers are great problem solvers. Agreed!
Being driven and lazy. I keep telling my wife that being lazy is a good think. She doesn’t get it! But I agree that being lazy is a good quality to have in programming.
Ability to understand other people’s code. Somewhat agree. Is it just me, though, but I see a ton of code that I’m having very hard time following! I would say it differently: great programmers write code that others can understand; great programmers write code for humans to read.
If you don’t have a passion for programming… can you excel in any other profession if you don’t have passion!?
Everybody needs to learn and work hard to get better. That’s why great programmers go the less traveled road.
Being good at math? Debatable. I think there is a connection, but wouldn’t pay that much attention to it. But yeah, I was good in math.
All in all, a good post by Steve.
No matter who. No matter what. No matter when. Short term.Long term. Any term. Writing good code is ALWAYS faster than writing bad code.
—Robert Martin (@UncleBob)
Is it because of pressure?
Is it because you want to be faster than others?
Or is it just because that’s the way you’ve been doing things and it has worked for you?
I hope it’s not the case. I hope you take the time to do it right. Because if not, as the saying goes, will you have the time to do it over? Or how will you look at it when you see the project codebase turning into spaghetti. Because it will.
I wish it was so clear cut. It’s usually not.
But I do believe in the theory of broken windows. One little “slack,” one not needed “if” statement starts this process. And then it goes downhill. It’s just a matter of time before somebody else puts another if. And another. Soon enough, you start searching where things have broken. It’s no longer easy to fix stuff. So you put another conditional.
That’s how things degenerate.
I’ve seen it many times in my career.
But I try to do it right. I think about consequences of my actions. Consequences of putting one line of code that will make things worse for others, worse for the codebase.
I take pride and always try to leave things in no worse condition when I found it. If I can, I try to make it better. I don’t always succeed. But I try to adjust. Learn. And always have “do it right” attitude. I think it matters.
If we had more people that cared about the quality, our dev world would be a better place.
Write Your Good Code First – blog post by James Sugrue and Uncle Bob’s quote that I found there that gave me motivation to write this post.
Here’s my take on the qualities from the post.
Always do it the right wayI cannot agree more. There are always people that will say that they’ll improve it later; that this is special and it needs a special condition. It’s a big bull… You do it the right way ALL THE TIME. Really no exceptions.
Good engineers know that the right way applies to all situations and circumstances. If there’s not enough time to do something the right way, then there’s really not enough time to do it. Don’t make compromises, the quality of your work is what ultimately defines you as an engineer. Make sure that all of the code you write is done the right way 100% of the time. Expect excellence from yourself.
Be willing to sufferI never considered this as an asset before. On the contrary, I thought that it must be something wrong with me. I like to develop solutions in my head, thinking hard about them, then implementing. And later find a better solution. I rarely ask others for help. And I usually come up with good solutions. Hmm, maybe there’s hope in my software engineering skills.
Great engineers first and foremost want to solve the problem on their own. Problem solving is a skill, a skill that great engineers take seriously.
Never stop learningIf you have been reading what I write on this blog, I don’t need to say anything else. This is an absolute must if you want to be considered a great software engineer.
In order to be a great engineer you must first admit that you don’t know everything, and then you must seek out more knowledge in every way you can.
Share your knowledgeI believe that’s what makes you valuable to the company you work for. That’s how you distinguish yourself from others. This is how you think “big picture”.
Great engineers want others to know what they know. They aren’t afraid of losing their position because someone else can do the same thing. Great engineers want to see their peers succeed and grow.
Lend a helping hand
Great engineers are team-focused and therefore are willing to do whatever it takes to help the team.
Do I need to argue with that?
Take your timeIt takes time to develop and improve on your skills. The only way to do that is by learning iteratively, practicing. It probably will take 5 to 10 years, or even more, for you to acquire great skills. To acquire that craftsman’s touch.
ReferenceWhat makes a great software engineer?, Nicholas C. Zakas
As programmers, we want to finish things fast. We want to impress our boss. We want to be better and always finish before others.
So we do. We finish things as fast as possible. Because the requirement was to complete the things that were on the list.
Just make it work.
What’s the end result? Code that is hard to read by others. Code that is rigid. Code that is fragile. Code that is over complicated. Basically, code that has the characteristic of “fast food” — it does what is supposed to, right?
Wouldn’t things be different if one of the requirements was “high quality.”
The statement is ambiguous. Sure. It means different things to different people. It could be more specific: “code should be easy to read, easy to extend, and easy to modify.”
High Quality. Enough said.
You could argue what quality really means. That’s not the point. Just stating that it has to be of high quality puts everyone on the same page: it communicates the expectation to the team.
“Why don’t we just add a special exception here.” No, you would say. That’s going to lower the quality of the code. That’s going to make the code more fragile and harder to extend. It does not meet the quality requirement.
I personally don’t need to be told that — quality is always on my list. I always try to make the code that I write be of high quality. I put focus on that. I don’t always get the results I want, especially after I look at my code after a period of time. But I learn. I improve.
There is just too much of low-quality code around. Too much pressure to finish fast and no pressure on quality.
Having quality a requirement would make a huge difference. I strongly believe that.
Even if your manager does not require it, “High Quality” should be one of the most important requirements when you write code. It’s not easy to write high quality code. That’s for sure. You learn with experience, by trying things out. Patterns develop after a while. Then you study a bit more. But having that focus we’ll make you a better coder and distinguish you from the others.
Code quality and the fat developer, very good post by Consulting jiujitsu
Uncle Bob wrote an excellent post, Speed Kills. Is there a tradeoff between speed and quality, he asks.
If by “speed” you mean delivering working softwarequickly and repeatably release after release after release; thenmaintaining high quality is your only option.
I couldn’t agree more. In the long run, the only way you can move fast at high speed is if you have quality. Time and time again, I come across projects that were finished fast, with the thinking that they will never be modified again. (I’m not even sure if that’s always the case, but rather that quality was not a requirement.) After a few months, things change. They often do. And the project needs to be modified. What is your speed then?
It would actually make more sense to rewrite the project. But that’s almost impossible. Too many dependencies. Too much coupling. Who can read that and understand? Too risky. At that point, the easiest thing is to do is just add a special exception, an “if” statement that would make the thing work.
And the project quality degrades.
And the speed decreases.
Frustrating? You bet. Especially if you are not the original coder.
Wouldn’t it be easier if it was written with quality in mind in the first place?
Speed Kills by Uncle Bob
If you consider yourself a good programmer, great! But is this going to hold true, two years, five years from now? If you are not going to learn new things, I can safely say that you’re going to be “out of date.”
If you want to stay still, you have to continue moving: being a good programmer means learning new things constantly.
Here are 10 Ways to Learn New Things by Philosophical Geek. Follow at least some of these and I think you’ll be covered.
1. Read books.2. Read Code.3. Write Code – Lots of it.4. Talk to other developers.5. Teach others.6. Listen to podcasts7. Read blogs8. Learn a new language9. Learn the anti-patterns10. Be Humble
Ben Watson, whose blog I just came across, lists the following Top 5 Attributes…
I think this is a very good list. I think effective programmers are humble. Why? Because you have to be able to work well with others. Just from my experience, it’s hard to work with people with a lot of ego.
You just have to love to learn. Effective programmers constantly improve. How do you improve? By finding new ways of doing the things you’re used to… better. You have to be exposed to new ways in order to do that. Being able to adopt and having a passion for the profession are essential.
Reference Top 5 Attributes of Highly Effective Programmers” href=”http://www.philosophicalgeek.com/2008/01/20/5-attributes-of-highly-effective-programmers/”>Philosophical Geek -> Top 5 Attributes of Highly Effective Programmers, Philosophical Geek blog
Here’s what Ben Rady, who calls himself software craftsman, states under his Statement of Values. I value similar things: I can sign my name under this statement. Excellent summary.
As a technical leader, I value:
* Talented People* Rapid Feedback* Individual Relationships* Facilitation over command and control* Continuous Improvement* Frequent Delivery
As a programmer, I value:
* Working Software* Clean Code* Rich Communication* Flexibility over efficiency* Sustainable Pace* Simplicity* Failing Fast over hiding errors
As a human being, I value:
* Courage, not cowardice* Humility, not hubris* Compassion, not callousness* Curiosity, not apathy* Discipline, not carelessness* Honesty, not deceit* Patience, not intolerance
ReferenceStatement of Values, Ben Rady