I've been a zone leader with DZone since 2008, and I'm crazy about community. Every day I get to work with the best that JavaScript, HTML5, Android and iOS has to offer, creating apps that truly make at difference, as principal front-end architect at Avego. James is a DZone Zone Leader and has posted 639 posts at DZone. You can read more from them at their website. View Full User Profile

Why Do I Break The Rules? And Who Can Stop Me?

12.29.2009
| 10966 views |
  • submit to reddit

I've been developing software for quite a few years now and I notice that sometimes I break the rules, those best practices that I know are right to follow.  With so many blogs, books and articles covering the best way to develop software, the temptation to do your own thing still can take over - even when you know it's wrong.

Ashamedly, I know that I've broken these rules in the past, as I'm sure most software developers have.

Test Driven Development 

There's no question in my mind that the best approach to developing any piece of code is to do tests first and then code. It focussed the developer in a different way than other approaches. You'll find that you start a fresh project with good intentions and write your tests first. Then, as you get further along the way, you start to run out of time, so somethings got to give - it will usually be your tests. 

There's no excuse for this. All IDEs have JUnit built in to them and any developer with experience knows that it works. All developers who think that unit tests can be skipped should read Pragmatic Unit Testing. The authors put it best when they proclaim "unit testing means never having to say you're sorry".

Ignoring Broken Windows 

Sticking with the Pragmatic Programmer series of books, one of the big lessons for software development is to have "no broken windows". A broken window is a piece of badly written code that exists in your codebase. If the window isn't fixed, then it will lead to other broken windows. 

While I might not be the first one to pollute a codebase, I'm as guilty as that person for not fixing, or at least logging, the issue. I don't know how many times I've gone through code, looking for where I need to add in my fix, and ignored rows of broken windows on the way. 

Once again, there's no excuse for this - I'm aware of the rule, I know that it makes sense, but I'm too caught up in getting my part done.

Mixed Up Spagetti Code 

These days most of us declare the wonders of modular architectures - being able to seperate code down to bundles of responsibility and redeploy those bundles anywhere. So we create a bundle (or package) with UI responsibilities, and then we create another for logic. How many times have you seen that logic code starts to creep into your UI bundle? Of course this doesn't become apparent until too late unless you've been following a test driven development approach, and have been testing anything that you can do on the UI through the logic layer. 

Of everything on this list, this is the one that I hate the most, and as such is the one that I'm least prone to.

Diving Right Into The Code 

It's new project day, and you know you're going to be using some cool technologies. Even if you're using the same technology, at least it's a clean slate. Nothing of the past three habits is going to get in the way this time. Or will it? 

The tendency to avoid analysis, and dive straight into the code is common with all developers. It's a natural thing as we like to get things running. It's even excusable if you do a quick run through, take the lessons learned and then go through an analysis stage. But it's the going back that's the problem - once we're in the code, we're happy there.  Sometimes we sugarcoat this as an "agile approach" but is it really?

The Solution 

The software industry would be in a much better state if we had a ready made solution to these bad habits. There's a common theme through all of my failures above, and that is time. Doesn't it look like I'm always up against the clock? Maybe that's my fault for not giving clear enough estimates. But if I bump up an estimate to ensure I follow all these rules, am I just going to waste the extra time I'm given?

Of course there are things that can be done such as peer reviews, but nothing can beat good programmer discipline. Maybe we need to introduce some kind of hippocratic oath for software developers? 

Tags:

Comments

Eyal Golan replied on Tue, 2009/12/29 - 11:21am

I totally agree with your points.

I  strongly see your point in the mix-up spagetti code section.

We use Apache Wicket as our front end in our application and lots and lots of our logic is in the pages and panels java code. This caused us for problem to use JUnit... Please tell me that I'm wrong, but unit testing for ui (wb ui) is not the most fun thing to do...

So recently I started trying to stop breaking some rules. For any situation that I need to do some logic, I create a class (or find a suitable one) and put the logic there. Then, my components (eg. pages, labeles etc.) call this class. Be that way, I make these classes spring-bean and inject them wherever I need.

And now, voila, I can add unit tests for my ui.

Works like a charm.

Great post...


James Sugrue replied on Tue, 2009/12/29 - 12:38pm

Thanks Eyal. When you can split up the code things work great for testing, definitely. The problem is in the legacy code that's still all tangled up- it's always difficult to go back and refactor large amounts of code like that under time pressure. But I guess if we can all stop breaking the rules on our new code, good things will happen.
James

 

Josh Marotti replied on Tue, 2009/12/29 - 1:58pm

I've never been afraid to tell a project manager that dates need to be pushed to add unit tests.  I love simply saying "The code isn't FINISHED nor READY until the tests are in place."  Having said that, I have regularly broken the 'TDD' rule... kind of.  I say "either write the tests before (for better design) or IMMEDIATELY AFTER you code."  I'd rather have 'after the code' unit tests than no unit tests from my developers...

Josh Marotti replied on Tue, 2009/12/29 - 2:04pm

I'd also like to mention that there is such a thing as 'too much'.

  • 'Too Much' TDD and you're writing unit tests for accessors
  • 'Too Much' avoiding the spaghetti code, and over overarchitected a monster that is difficult to read and is so uncoupled that you are passing the entire application from one module to another.
  • 'Too Much' avoiding diving into code and analysing can become analysis paralysis.  Or, even worse, solving problems before you code.  I can't tell you how many times I've worked with junior developers concerned with a sorting algorithm where even brute force would have been fine because they made far too many calls to the DB causing the DAO layer to be the chokepoint of the entire app.
So, yes, try to not break the rules, but remember moderation!  :)

Bharat Kondeti replied on Tue, 2009/12/29 - 3:00pm

I totally agree with all of your concerns. I am guilty of many of these mistakes.


I totally believe in TDD and all its benefits, but sometimes when I am writing code alone I am tempted to write code first resulting in skipping some test cases. This is where pair programming comes into picture. I realized that whenever I am doing pair programming I never slack doing TDD, may be because of guilt or may be because other person is watching over me.


Fixing broken windows is a commitment from the team, team leader, product owner and all the stakeholders. Sometimes we put in hacks or choose to write code not the right way because of many reasons like looming deadlines, lazy / inexperienced programmer, in the hope that we can re-factor the code later in time etc. etc. As a team, a commitment has to be made to get these fixed. As a team leader, he should be able to convince the product owner why there is a need to go back and fix some of the code and why bad code is written in the first place. As a product owner, he should make an effort to remove many of the reasons that caused to write bad code and lay out some standards. As stakeholders, they should think in long run and should understand the problems with broken / bad code.


Writing mixed up spaghetti code has many reasons. Inexperience, not doing TDD or writing proper tests, no code reviews etc. Many of these can definitely be resolved by pair programming.

Byju Veedu replied on Wed, 2009/12/30 - 4:06am

I am with fortknox . It all depends on the situation. There are two sides for a coin always!

Jakob Jenkov replied on Sat, 2010/01/02 - 8:24pm

I second that. It always "depends". Great developers know when they can break the rules safely. Use your judgment in each and every case.

TDD - it's fine when you know ahead of time exactly what you are about to program. But haven't you ever been in a state where you don't really know that? You sit down and start writing a few experimental lines, then add some more, to come up with an algorithm for solving problem XYZ. You don't really know the input parameters yet. Maybe not even the return value. You may not know from what other component you get that information your algorithm needs. You just sit down, play with it, until the algorithm works. Then start looking for where you can get the needed information, and in what format the output is needed. How can you writ a unit test during this stage, without wasting your time? How can you not "dive right into the code" ? Well, you can code on paper, but the end result is the same, isn't it?

Broken windows - a simple solution could be to insert a TODO in the code. Then have a code scanner create a quality assurance report listing the TODO's. Together with the test results, the "style" checks, and the code coverage report. Then, change the success criteria to include these metrics too. We are not done until ALL the lamps are green, or someone with the right number of stars says it's green enough. Human beings are imperfect. We need quality control to weed out the mistakes we make. Trust is good. Controls are better. 

Spaghetti code - some business rules are so weird that there is no way you can implement them without the code turning into spaghetti. I have seen that lots of times, when implementing old, human rules (e.g. governmental) in software. Experienced domain experts could normally take all these rules into consideration and maybe even make a judgment based on gut feeling. Once you translate that into computer instructions it can get messy though. Again, a "TODO attempt clean up" could help.

And what about starting to program without having the full spec? Never done that? Never been in a situation where it was a waste of time NOT to do that?

Personally, I never just blindly abide by best practices or other half religious beliefs. Our industry is full of them, and some of them are actually bad advice. Unfortunately inexperienced programmers pick them up immediately because they sound like common sense. Like exception hierarchies. Like the SystemException / BusinessException , like @Inject, like so many other things that are not all they claim to be, once you fully analyse the use cases they are intended for.

I think I have yet to experience any rule that has not called for an exception. Even checking in code that breaks the build - if you really, really need to save that temporary code now. Avoid it, yes, but sometimes you determine that in this or that particular situation the costs are less than the benefits. So you break the rule.

 

Alex(JAlexoid) ... replied on Mon, 2010/01/04 - 10:03am

The authors put it best when they proclaim "unit testing means never having to say you're sorry".

I am sorry to get into others' quotes, but that quote is a heap of bull****. TDD is no svaiour. And a good tester will say, that there is an infinite number of tests.

And a lot of times TDD upfront can be a headache.

And basically everything has to be taken in moderation. There are no ultimate cures, unless we have assembly language with one command "DO WHATINEED".

Jeroen Wenting replied on Tue, 2010/01/05 - 2:17am

"Doesn't it look like I'm always up against the clock? Maybe that's my fault for not giving clear enough estimates. But if I bump up an estimate to ensure I follow all these rules, am I just going to waste the extra time I'm given? "

In my experience it doesn't matter what you estimate. Whatever estimate you provide, the actual number of hours budgetted for the job will be less (usually 50% or less of the estimate provided). So maybe you are too honest in your estimates, not too inaccurate.
For example: at a previous project we were asked to provide an estimate for adding a new feature. After some thinking we came up with an estimate of 80 man hours of work. Despite my warnings, this estimate was sent to management who passed it on to sales. Sales sold the project for 40 hours of work. We got it done in 60 (so well under our original estimate), and ended up being blamed for going 50% over budget. Showing people our original estimate didn't matter, it had been decided higher up that development would take the fall for the failure of sales to sell something at a realistic price.

Jeroen Wenting replied on Tue, 2010/01/05 - 2:36am

"I've never been afraid to tell a project manager that dates need to be pushed to add unit tests"
And the answer almost universally is that there's no time, no budget. What counts is code delivered, and tests aren't delivered. This has gotten (in the project I'm currently working on) to the point where our dev and test servers are used mainly to check whether earfiles will deploy without errors. Testing takes place almost exclusively on the acceptance test machine, and we have a strong feeling that the customer doesn't even test there but just changes test states to "accepted" for things they want to see in production without actually running test.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.