It's all in how you approach it

Posted by Brett Schuchert Mon, 21 Jul 2008 13:15:00 GMT

I was painting a bedroom over the last week. Unfortunately, it was well populated with furniture, a wall-mounted TV that needed lowering, clutter, the usual stuff. Given the time I had available, I didn’t think I’d be able to finish the whole bedroom before having to travel again.

I decided to tackle the wall with the wall-mounted TV first, so I moved the furniture to make enough room, taped just that wall (but not the ceiling since I was planning on painting it) and then proceeded to apply two coats of primer and two coats of the real paint. I subsequently moved around to an alcove and another wall and the part of the ceiling I could reach without having to rent scaffolding.

I managed to get two walls done and everything moved back into place before I left for another business trip. My wife is happy because the bedroom looks better. I did no damage and made noticeable progress. I still have some Painting to do (the capital P is to indicate it will be a Pain). I eventually have to move the bed, rent scaffolding, and so on. That’s probably more in the future than I’d prefer, but I’ll do it when I know I have the time and space to do it.

Contrast this to when we bough the house back in March. I entered an empty house. I managed to get two bedrooms painted (ceilings included) and the “grand” room with 14’ vaulted ceilings. I only nearly killed myself once – don’t lean a ladder against a wall but put the legs on plastic – and it was much easier to move around. I had a clean slate.

Sometimes you’ve got to get done what you can get done to make some progress. When I was younger, my desire to finish the entire bedroom might have stopped me from making any progress. Sure, the bedroom is now half old paint and half new paint, but according to my wife it looks better – and she’s the product owner! I can probably do one more wall without having to do major lifting and when I’m finally ready to rent the scaffolding, I won’t have as much to do. I can break down the bed, rent the scaffolding and then in one day I might be able to finish the remainder of the work. (Well probably 2 days because I’ll end up wanting to apply 2 coats to the ceiling and I’ll need to wait 8 hours).

Painting is just like software development.

Top Refactorings 2

Posted by Tim Ottinger Thu, 26 Jun 2008 01:10:00 GMT

This has been done before by another mentor, and it was fun. I’ve been watching my use of refactoring tools, and here is my top five list of seven most-used refactorings:

  1. Rename
  2. Introduce Variable
  3. Extract Method
  4. Inline variable
  5. Inline method
  6. Move Method
  7. Change method signature

You might guess that I’m doing a fair amount of refactoring on legacy code.

I was suprised how much I’m using introduce/inline variable, but quite often I’m doing that to make a block of code ready for method extraction. Having broken out small methods, I sometimes find a larger method to extract, and then I inline the use of smaller methods. It’s sometimes hard to find the right level of generality.

I’d have trouble imagining that the first three weren’t everyone’s favorite refactorings.

Discipline often directed at the symptom, not the cause 5

Posted by Brett Schuchert Sat, 01 Mar 2008 16:18:00 GMT

Have you ever heard something like?
If the developer just had a little discipline and did it the right way, we would not have this problem.

That’s often a sign that the way something is getting done is hard to do, not supported well or just plain works against against you.

Here’s an example I recently came across…

In a particular organization, part of their build system produces “project” information to allow for development on multiple platforms and with different C++ compilers. That’s excellent, it sounds like a great tool. For a developer to get started, he/she:
  • Checks out the source tree
  • Runs the script
  • Starts working

So far, everything is great and this part of their build system is essential to their environment – and good in general.

Here’s the next part…

To add a file to the system you have to:
  • Create the file
  • Update project information
  • Rerun the script to regenerate project information.

When I asked how long it takes to add a class, I was told about 5 minutes. So if I want to add a header file and source file, it takes 5 minutes. That’s a big problem. Why?

After this discussion, I heard one of the senior people lamenting that a developer had put another class in an existing file rather than creating a second file. He said something like “If the developer just had discipline, he’d to the right thing.” Those darn developers.

It takes 5 minutes to add a few files to a build. That does not include build time. That’s just the time to configure the build information.

Does 5 minutes seem like very much time?

Here are a few more thins I noticed(before I knew about the build system):
  • Some header files defined multiple classes
  • Some source files had the methods for those multiple classes
  • Some of the header files had names that did not match any of the classes defined in that header file

So is this a problem?

Here’s an important rule from Jerry Weinberg:
Nothing + Nothing + Nothing eventually equals something

5 minutes may not seem like a lot of time, and if it were isolated, then it’s probably not a problem. On the other hand, when you multiply it by a team and time, you end up with big problems.

Imagine, you need to use class X. Its header file is actually named Q.h and by the way, classes T U and L are defined in that file – none of which you want to know about.

So your class now has phantom dependencies on T, U and L. Also, how did you find the right header file? A quick search (time wasted). Someone changed U, so you end up having to recompile even though you don’t care about nor use (wasted time). I’m sure you can come up with a few things on your own.

So what do you do about it?

OK, first, do not throw the baby out with the bathwater. The original tool solved an important problem. But the first rule of problem solving, again from Jerry Weinberg:
Every solution introduces problems
The problems include (but are not limited to):
  • Time wasting adding files
  • It requires discipline to add new files, so it doesn’t always happen
  • A name is wrong, but it’s a pain to update the build configuration, so it doesn’t happen – not all the time, just every so often

Little by little, things get a bit more chaotic.

So now that we’ve observed a problem – some waste, we need to find a way to remove the need to update the build information and regenerate to even work.

I don’t know what’s going to happen with this group. They are hoping to perform some refactorings. Their system has quite a bit of coupling. One thing we can do to reduce coupling is:
  • Introduce interfaces
  • Inversion of Control
  • Identify seams and use some of Feather’s stuff to introduce them
  • Etc., the usual stuff to introduce seams and break dependencies.

But many of the refactorings they’ll want to use will involve creating new classes. Since that takes a little bit longer, it will slow everything down – or seem so daunting, it might not happen at all.

Here’s a personal example. A few years ago, I built the security system for one applications and then a suite of applications with single sign on. When I initially introduced the security system, many people wrote tests that would forget to log out, causing problems in both the real system and the simulator.

I kept grumbling. I though, “if people would just do it right, there wouldn’t be a problem.” If they just had a little discipline.

Independent of whose fault it was, it ended up being my problem – and, quite frankly, it was my fault as well. The solution was actually pretty easy:
  • Create an abstract test base
  • Change tests to use it
  • In the setup, the base logged in
  • In the teardown, the base logged out
You might think, “Duh!” and in retrospect, so did I. But that few minutes of effort:
  • Reduced code duplication
  • Increased the stability of the tests
  • Made it hard for people to mess up (so long as they used the correct test base – and I updated all of the tests that needed it, so going forward, people had correct examples upon which to base their work).

Ultimately, this removed a lot of my wasted time

Detecting waste is the first thing. Until you know it is a problem, you cannot do anything about it.

So, the next time you think something like:
  • If that person was only following “the rules”
  • If he/she just had a little more discipline
  • Stupid user, they should not have done that

Ask yourself if it’s possible that those statements are directed at the symptom, not the problem.

On Being Stupid 16

Posted by Tim Ottinger Mon, 10 Sep 2007 10:16:00 GMT

This was posted originally to a mailing list, but is reproduced here essentially unchanged by request of a friend.

I frequently see code (written by others) that is completely double-spaced, heavily commented, loaded with many abbreviated or meaningless variable names, and hundreds of lines long. In order to read the function and understand what it’s doing, poor Tim must wear out a mouse, skip comments, and track the variables on paper. A “smarter” programmer could just load it into his head, I suppose, but not the simpleton who writes this email.

I’m not smart enough to just read it from top to bottom and understand it. Sadly, when I read through and understand what in the heck the thxIniFvt variable is doing, I will forget it by the time I figure out the purpose(es) of pszVbt. I can spend all day, or even a few days to figure out a method, and that’s an admission of feeble-mindedness to be sure. I guess I’m not up to the level of some of the rapid hackers. That’s a limitation I face most days.

I find that I can sometimes understand a method like that only if I just delete all the blank lines and comments first, then reformat to break lines, then inline all methods with seven or more parameters, and then start renaming variables, extracting explanatory variables, and extracting explanatory methods. I may have to break the method into classes even. I guess I’m not one of the smart kids.

I used to be one of the smart kids. I once built a module so complex and fragile that nobody but me could figure out what to do with it. It was all tables and indicators, and stunningly clever. I am so ashamed that I wrote it. It was such a mistake that they eventually disabled it rather than field it in such a state. That was years ago, but so memorable to me. Other programmers said it was like the inside of a swiss watch, all delicate and perfectly balanced, and scary to mess with unless you first knew exactly what each part was doing, and why.

I would like to be faster than I am both mentally and in the sense of quickly producing code. I’d like to be a little less intimidated at the start of a project. .But I would not want those things if it meant building crap that people who are not appreciably more talented than myself would trip over every day. Instead, I sometimes wish I could teach the really fast, smart kids how to dumb down the code for the rest of us morons to read.

The funny thing is that dumbing code to my level doesn’t make it harder for the smart kids to use it, and sometimes allows a compiler to do a better job with it. I guess stupid isn’t so stupid after all.