Thursday, February 26, 2009

Stack Overflow #41

Oh, hey! I got a small mention in Stack Overflow Podcast #41. It was a quick mixed reference to my Object Mentor blog entries Curly's Guide To Software and Outliving the Great Variable Shortage.

It's not much, but I'll subtract three or four seconds from my fifteen minutes. :-)

Global Variables

Know what I hate about global variables? Besides "everything", I mean?

Seed And Harvest is evil. Globals propagate the seed-and-harvest idea which makes the existence of globals even more odious.

More Remote Pairing

Some days it is a struggle.

My network disconnected and reconnected a few times. That made me lose my session and have to restart.

We determined the dark background that looks great on his screen was causing trouble, and had real issues getting VS.NET to return to white background defaults. Was much harder than one would suspect.

Got some code moved and checked in, got green tests. Explored nhibernate space to learn how to do some of our specialized queries.

Noted some overkill queries. Overkill queries get every object of a given type and then throw away all that they don't need. These full-table-scans cause performance engineers and DBAs to break out in cold sweat. We're going to build/rebuild some NHibernate chops and chase these down with an axe.

Observation: almost all the NHibernate articles I found through google are tutorials on writing the XML (or appear so at a glance). Not a lot of them are about using it to do anything. I guess the tail does wag the dog sometimes, or the use is supposed to be so obvious as to be beneath need of tutorial.

Version control is your friend. We had a rename refactoring go wrong in the most puzzling way, and a nice, safe revert was deemed an attractive choice. Ron never goes backward, but Ron is not me. I go backward if it allows me to recover confidence and step forward all the more boldly next time. Sort of a "regroup".

Observation: if you're remote pairing, you can have garlic-laden foods for lunch. :-D

Learning so much!

Afternoon had more application glitches than technical glitches, though we did lose audio and video a couple of times. It just wasn't our biggest problem.

We got the architecture team together and made some good progress on plotting our future data access patterns & plans. So I guess this stuff really is working. We even got some stuff done, for small values of "done."

Wednesday, February 25, 2009

Remote Pairing Day 3

Pairing from my house, using my broadband today. Took extra time to get set up, because I didn't have an office all squared away. Not yet. We're working on it. Today it's the dining room table for me.

I was concerned because we had a late drive last night and didn't get as much sleep as usual. I didn't make the agreed upon rendezvous online, so my partner was left waiting. Again. This cannot be a pattern for me. This whole experiment is dependent upon us being able to conduct meaningful work from a distance. Tonight, more sleep, sooner waking. I don't want to flip a bozo bit.

This morning, I tried using WebEx and skyping from my Ubuntu box for video. Skype installed okay, but will not use my logitech webcam. Ekiga will do that, but my partner apparently is firewalled in from stun servers and can't connect with Ekiga. That's two or three programs that we can't try because of that. Maybe we can get the admins to open a port or two for us.

WebEx was mostly okay, and the company already has a relationship there. Connections weren't too laggy and sharing control was not too trying at all. Fullscreen mode was useful and clear, and I could see the cursor in text mode. We moved to 255-color mode to save bandwidth but it didn't really change anything for us. It was overall a decent experience as long as I didn't use my mouse's scroll wheel. If I used it, the app would immediately scroll all the code off the window. It would take huge jumps.

With the skype disappointment, we decided to go voice-only with google voice and video on the Windows box. That worked well enough, because we want the screen-sharing to be fullscreen anyway. I didn't really miss the video.

The other thing I learned was NOT to use a bluetooth headphone for this. I could hear just fine, but as with every other device I've tried to use with bluetooth, my voice was a mess. It was messy and broke up. I've never had satisfaction from any of the bluetooth devices I've used. The other end always says it's muddy, broken, and underwater. I've even tried the jawbone devices and Libby said it was awful. So it's all-wire for me.

We got into the next phase of our work and found that the inheritance tree didn't really support our work. We have some architecture-type work to do to move ahead. Nice. It's a good thing, I think, and I'm learning the app better all the time.

Insert lunch break here

In the afternoon I brought in the good chair from the to-be office, put my laptop up on a stand so it was at eye level, and actually was working without discomfort. I was enjoying the changes, though I noticed the system was getting more and more lag.

Mid-afternoon my network went wonky. I looked at the router and found that there were about ten users other than my family's computers. It was about the time my son got home from school, so I'm betting that everyone around was using my wifi. I don't begrudge casual usage, but When I start getting disconnected from my workplace, that's too much. I had work to do, and suddenly no bandwidth.

I popped into the wireless router and added a password. I also found some other settings in the router that were a tad distressing (like renewing leases every two hours!?). I squared those away. Eventually I got it set up on WPA2 and all my devices connecting, and life was good, but that was well after 5:00. I hate losing a day to administrivia. My wife (also an internet junkie) hated the the router reboot multiple times in order to take on new settings.

In the meantime, though, I have a feature that is less than half done, and I really want to finish it ASAP. It's really a couple of simple functions right now, and a skeleton for a database gateway object to support it. Code coverage is good, code and test are nicely refactored, and we're a short distance from getting it done. I really want to make tomorrow the best day ever.

Lessons Learned

If you're going to remote, guard your bandwidth.

Also, if you spend time in Ubuntu, make sure you have the system tray in your desktop panel. I ended up wrestling with wifi-radar and other stuff before I realized that the networkmanager applet (nm-applet) was more competent and already running. I didn't see it because it was in the system tray (which wasn't present on my desktop). Sigh.

On the first day in any new location, I suppose you should expect to have troubles with the local environment.

Lag is your enemy. I can't imagine how frustrating this must be on the other end, waiting for the screen to scroll or the keyboard buffer to empty from my side of the wire.

Forget bluetooth. Or at least try it out with your partner before relying on it. I can't say all bluetooth headphones stink, only that all of them I've tried stink. Stick with wires.


Today started the morning with WebEx for screen sharing and used the google voice and video for voice only. It worked pretty well. In the afternoon we used TeamViewer limited-time preview for screen sharing, and the google voice and video application. At least as often as we were able to stay online.

We attempted to use yakkle and ekiga but we had corporate firewalling issues. We may have to get them to open some ports (stun servers, udp) so that we can try these other products. I would like to see us using something free if possible. I don't need remote pairing disincentives.

I'm not currently set up to screen share from my Linux box. I would really like to see that happen but I am willing to call an end to net tech adventures for the week.

Tuesday, February 24, 2009

Remote Pairing Day 2

I'm in a new position, and it is part of the deal that I work from home. Anybody's home. I'm learning the art of remote pairing, and will give some pointers here as I explore the space.


Today I want to mention some technology we're using. So far I've tried a few free remote solutions, and found them to be awfully laggy and troublesome. I'm so open to an open-source solution or two.

So far I've done the A/V portion using google chat extensions and skype. Of the two, I had google drop out less and they both keep up to date pretty well. I was happy that there wasn't a lot of lag and pixelization with either. The video is grainy, but it does help to have facial expressions in a discussion.

The screen sharing we've liked best have come through commercial services LogMeOn and TeamView. We've been using the free trial editions, and both seem to work very well. By "working well" I mean that
  • Connection isn't dropped too often
  • There is no troublesome degree of lag
  • We can work trade driver/navigator without "mother may I" coordination
  • It looks roughly the same on both sides
I would most love to add "works for Linux or Windows" to that, but that's not strictly required. I'm doing windows-only this week, and we can run putty or msys for text-mode linux session sharing. I wonder if this is the first really legitimate use of Windows I've had in a few years. If that's where all the screen-sharing, pair-programming magic is, then windows has a place in my toolbox after all.


I also attended my first architecture meeting via webcam & mic. It could have been better, and I eventually fell out of the meeting. But it was helpful for a while.

With the lag resolved, it wasn't nearly so bad. I was able to even listen on conversations with other developers when we hit snags. We didn't produce a ton of code, but we were able to produce a number of tests and refactor them pretty well. The code became clear enough that we saw some flaws in our approach and corrected them in flight, and stayed within a very few minutes of the last green test run at all times.

Concentrating the fact that's I'm peeking through a keyhole, I actually skipped the 'red' in a red-green-refactor cycle. When I realized it, I commented out some code (only one line) and got the red bar I needed. Then I uncommented it and got a proper green bar.

I also have not been switching partners so much. I have a partner (also named Tim, though I'm Ottinger and he's Gifford) and we've been working together Friday, yesterday, and today. It's going well, though I know that as I get more of the system loaded into my head we should be starting to trade partners. I got to work on that "load program into head" system.

I'm relearning RhinoMocks, C#, Visual Studio, and Resharper after a long hiatus. I'm working with good people, and we're making some progress and might have something worth showing someone tomorrow or the next day. And I'm doing it from a great distance. It really hasn't been frustrating as I expected. The technology is much better than last time I tried, and the task is discrete enough.

Lessons Learned

Punctuality: I got mixed up between timezones and my partner had to wait for me or go on without me. This won't be a problem in Illinois, but working from Indiana meant that I have to know what time zone each watch and clock and computer is on. I need to be ready when the parner is ready, especially when we've pre-arranged a time.

Second computer: though a second computer is normally a distraction, it might be good for remote pairing. if the second computer provides the A/V and stands by with documentation on language/frameworks/etc then it might not be a pairing smellat all. It might even be a good thing.

Equipment: I want more monitors. I love my on-ear active noise reduction headphones. And a laptop I can take from room to room if one space must necessarily be loud for a little while. And wifi. Mmmmm... wifi.

Technique: I use the online stopwatch to count down 48-minute pairing sessions, after which we try to take 12-minute breaks. It saves eyestrain and gives your head a chance to clear between sessions. We're actually struggling to make the breaks last that long, but I wanted to give this system a fair shake. Oh, and we pretty much live by the ABCs if you ignore the C bit.

So far, so good!

Wednesday, February 18, 2009

Pork Barrel Agile Failure

So here is a failure mode I finally had time to think about. I saw a version of this play out, but here's the basic idea:

The Customer doesn't get as many stories as he'd like, so he pads the story with functionality that has a lot of leverage. Then when it's done, he can use it many different ways. This makes it a little hard to see the original user request in the fluff, but it does accomplish its original task (too).

The story is too large, but it is pushed to development, and developers take it on by sending a few guys offline to work on it for weeks/months.

In the meantime, a developer realizes that this feature is considered critical, so it has to be pushed. He has other features he would like to ship, but they're not related to this one. On the other hand, if he can sneak in some of his feature into this story, he is assured it will be released. This makes the story later, so there's more overtime, and it takes on more testing risk, but it's a good stalking horse.

It's a pork barrel. Each participant puts things into it that they want instead of addressing the real need (sort of like the stimulus package that gave a break to manufacturers who produce wooden arrows of a given circumference). The eventual product no longer represents the customer's wishes nor the cleanest possible architectural implementation of that need. It has its own special interests and agendas.

I suggest that this is a bad thing.


Agile via Sound Bites

There was a long, multiparty discussion on the XP mailing list recently. A fellow was struggling with some issues about self-managed teams and taking direction from the Customer. There was a lot of misunderstanding going on.

It reminded me that Agile is something that takes some training and coaching. I'm not currently in the "agile coach for hire" business currently, so I'm not just drumming up work here when I say that any team considering a transition should hire a good coach. Hearing a few words about agile at a convention, reading an article or two (or a few newsgroup posting, God forbid!), or watching a video lecture are not sufficient training for agile practice.

Agile software development is clearly not brain surgery. The ideas are simple and deep. The problem is that the sound bites are pithy and (to the outsider) pretty shallow-sounding. The case in point is that the mailing list participant had the entirely wrong idea about what a self-managing team is, and what it means to the organization. After many cases of asking the wrong questions (challenging a false impression instead of asking what one wants to know) the visitor realized that he'd fallen prey to sound bites without having a fully story. That can happen to anyone, anywhere. I've done it.

But agile software is about values and practices that help live out the values. It is simple, but goes very deep. A lot of things can't be easily understood from a cursory glance or a seminar days or weeks or months ago. The best way to have success in a transition is to have a coach (or maybe two?) come and lead the teams into the proper forms and functions. Eventually a team can tailor the process and manage themselves, but they have to learn the way first.

Now I'm working at a pretty successful agile shop that I helped transition last year. It's nice here. They get it. Bob Koss and I spent time getting the right practices in place and teaching the values. It's a good gig. But they didn't get here from watching a couple of Agile videos, or reading a skinny book.

Thursday, February 12, 2009

Clean code: Writing Functions

Uncle Bob writes an awful lot of code. Not all of it is in his Git repository, because he is also a consultant/coach and writes code for his customers. Here he describes the current state of his practice regarding writing code that is clean.

Clean Code Talks: Writing Functions

The SOLID principles as motivational posters.

I want a full set of SOLID motivational posters for every client, employer, and beloved code influence in my life.

Friday, February 6, 2009

Coding your way out of Fear Of Change

You can avoid many problems with process elements that are conceptually simple.
  • You have to set a coding standard and stick with it (one that your tools support).
  • You have to have a reliance on automated tests.
  • You need QA to vet that automated testing, rather than substituting for it.
  • You need constant refactoring to keep the code in its simplest state.
  • You need pair programming so simplicity and readability will trump individual taste.
  • You probably need some pre-commit triggers in your version control.
That's nice for green-field development, but what about the rest of us?

If you are already in trouble, you have a long road ahead of you. You should get a copy of Michael Feathers' excellent legacy code book. You should also get a copy of the clean code book. Having copies of Refactoring is a good idea. Education is a start. Have them read. Have them presented. Organize brown-bag lunches or catered pizza buffets.

You will need to start a program of improvement concurrent with education. You'll need a small cleanup crew, but the responsibility for clean code has to extend to the whole development group. All new code has to be written according to the green field rules above.

The cleanup crew should take on the worst elements in your code base. They are easy to identify. They are the largest files with the richest change history in your SCM tool. If the file is in the top 10 by size and the top 10 by number of commits, then it's a very good target. If you want to get a weighted score, consider changes as double the weight of lines.

Pick a target and use the legacy code techniques to get the code under control, which is to say "under test".. Surround it with an unreasonable number of tests, and feel free to extract class and extract method until the code seems absurdly simple. Break it into multiple files by class even if you're not in Java. Be particularly ruthless where wizard programmers have added "magic" into the code. You can't afford clever code if you are trying to increase productivity/velocity.

This work can be grueling, so rotate developers between the cleanup crew and the normal feature team. Nobody who isn't disposed to this kind of work should have to do it very long, but everyone will benefit from learning to clean code.

You should disband the cleaning crew and return everyone to feature development when none of the remaining code is significantly larger, more volatile, or more fear-inducing that the rest. That might take a few months. It might take a few weeks. The team will be able to decide.

The work is made easier by a mentor who has been through the process once or twice, and has read all of the books, or at least quite a bit of each. But it will be hard. At the end of the process you will have code that is well-tested and which requires less fearful change management.

This sounds like a work-stop, and plenty of people will disrecommend it. Having managed in a code base full of magic, I have a different understanding of the issues. Perhaps the thing to do is to give the team the choice of working this way for a fixed period, and then see if you want to continue.

The more canonical way of managing a mess is to follow the same path, but don't pick targets. Instead, work on features and clean all the code you have to touch to implement the feature. This way, the code with the largest number of ongoing modifications is cleaned first. It's not at all an unwise decision, but it is difficult to justify why a nearly-cosmetic change suddenly takes two weeks. If you're dealing with "change avoidance management" then you'll have to fight more. Perhaps that is why Agile values courage. But if you can't afford it, then a cleanup crew is an alternative.

Monday, February 2, 2009

Code Doesn't Lie

I'm learning my way through Pylons, which really is very simple (so far) but the tutorials are all wrong in different ways. Even different versions of the same one. One will reference sa.something or orm.something but never import or define 'sa' or 'orm'. Others refer to things without prefixes, but show imports "as sa" or "as orm". Yet others leave out whole sections of code to type.

That's the problem with docs, even the best of them. They lie. They may not have lied originally, but eventually they lose touch with reality and begin to say things that are not true. I don't know the editing snafus that lead to several copies of the QuickWiki tutorial all being wrong, but I know that it takes extreme vigilance to keep a document from going south. And I know that as you re-edit, you begin to be less wary. You start to read what you meant instead of what you wrote.

I'm sure this is the same case. The subject matter is quite simple, really (kudos to the team!) but I spend considerable time looking for working code samples that show the code in a form that really works. Then I can correct the incomplete instructions in the tutorial and move on. I'm working on an app of my own in parallel, so time spent researching bad docs is impairing me.

But the code tells the truth. Working, runnable, real code is reliable. If it drifts from reality it quits being working, runnable, real code. To the extent that code tells a good story, it is a better tutorial.

At this point, I think I might have been better off to start with a small app like the QuickWiki and a two-page explanation of how things fit together and the paste commands you need to make things happen.

This once again shows me how important it is to guard the readability of our code. The part that doesn't lie also should not mislead.

Looking for interesting work

I'm currently looking for some interesting work in northeast Illinois or southeastern Wisconsin, or possibly some minimal travel + work-from-home. If you know of some good people needing an agile/TDD mentor you might be interested in my resume.

In the meantime, I'm putting some time into building up my web development skills with python and pylons, the book project, and setting up an Ubuntu server for my church.