Category: General

Pubescent Software

A co-worker of mine described the current state of a certain software company (paraphrased):

It’s no longer a start-up.  It’s bigger than that.  It’s not a mature company either.  It’s somewhere in between.  It’s pubescent.  It’s gangly, awkward, and clumsy.

I’d say that’s a pretty good description of the phase between start-up and mature company.  It’s no longer small, young, and agile, but it isn’t yet old and fixed in its ways.  The clumsiness comes from not knowing quite how to operate.  It can’t continue to operate in the way that it did (in “start-up mode”) because things no longer fit.  But it also doesn’t have down the efficient business processes that come with experience.

Do it right, or do it wrong, maintain it, then eventually do it again.

You may have heard the following saying:

“Do it right, or do it twice.”

In software development, it’s more like:

“Do it right, or do it wrong, then support that wrong, then eventually do it again.”

This is something that I keep thinking about with software development.  Why do we do things wrong the first time?

  • It’s done under the guise of being “agile”, because we want to satisfy customers as quickly as possible.
  • We lack the knowledge to do it right the first time.
  • We tell ourselves that we’ll go back and fix it later (but we rarely do).
  • We feel like we lack the time to do it right, right now.  A quick fix is quicker.

Far too often, though, such development ends up costing more time and more effort in the long run.  The band-aids and duct tape approach only leads to more work in the long run.  Instead of implementing a solution once, you built it the first time, deal with all the related maintenance headaches, then end up re-building it.

Do it.  Do it right.  Do it right the first time.

“I don’t care.”

When I hear someone say “I don’t care” regarding a decision in a meeting, it raises the hair on the back of my neck.  It causes the following things come to mind:

  • I have no vested interest in the outcome one way or the other.
  • I don’t value whatever resources are involved in the decision being made.
  • I would rather be doing other things with my time.
  • Your suffering (or anyone else’s suffering) doesn’t matter to me.
  • I’m fine with making short-term gains in exchange for long-term pains because I’m not concerned about the long-term impact of this decision.

 

There’s often a better, more specific way of getting your point across:

  • “I’m not sure this decision has any impact on me, so I’m fine either way.”
  • “You choose whichever option you think is best.”
  • “I’m not sure I could recommend one option or the other… they both seem [good/bad].”
  • “Do what you need to do in order to make [the goal] happen.  I’ll support you in doing this.”
  • “Let’s go with the best long-term option.”

“Not sure why”

I just saw a comment like this in a piece of code written long ago:

“Do this particular thing because it behaves like this.  Not sure why.”

That, to me, is a code smell.  If you aren’t sure why a particular piece of code is behaving the way it is, it’s best to take the time to understand why it is behaving the way it is, rather than compensating for it in other places.  Compensating for unknown behaviour leads to messy code and unexpected bugs.  It makes maintenance harder, because you then have to update code in more than one place.  Duplicate code = duplicate bugs = more maintenance = it takes you longer to get new features in.

If you aren’t sure why – learn why!  An hour spent now saves ten hours spent later.

If you don’t add logging/auditing now, you’ll regret it later.

At some point in time, you will be given a task like “What happened to X?  Why can I no longer see it?”  or “Why does the date on X say ‘Dec. 31’ when it previously said ‘Jan. 1’?”  With any sort of complex system, these kinds of questions are inevitable.  A user changes something without telling another user, or a weird process messes with data, or worse yet, a bug happens (which is almost inevitable).

With if you are properly logging an audit trail, these kinds of questions become really easy to solve.  Want to know who deleted X?  Check the logs.  The logs don’t even need to contain all the detail – just a general idea.  For example “User ‘Gordon Freeman’ deleted X on Aug. 1, 2012” is detailed enough to tell you who did it, and when it happened.  It’s so much easier to add some basic logging in at the start, then to spend time trying to track theses kind of things down after the fact.

Save yourself some time.  Add logging/auditing right now.

Fuzzy Pagination

Have you ever been browsing a website, viewing a list of items, and had it display 20 out of 21 items?  Don’t you just love clicking the “next” button to see one more item?  I don’t.

Pagination – the idea of breaking up data into pages of a set length – is often necessary.  When querying data, and not knowing exactly how much data is going to come back, you need to put a limit on things.  Imagine searching Google, and it loading up a web page with all 550,000+ results for “discount Koala meat”.  I’m pretty sure that would crash any browser – especially on a memory/CPU limited mobile device.  So rather than returning all results, it breaks the search results into pages of a reasonable size.  But what is a reasonable size?

One frustration I have with sites like Amazon.com is that they will display page sizes of 20 items or so.  But what if my query returns 21 items?  Do I really want to make the user click the “next” button to see a single item?  What if they want to see items on both pages at the same time?

Situations like this make me want to implement some form of fuzzy pagination.  If n is the page being requested, we examine page n+1 (if it exists).  If page n+1 does exist and is the last page, and the number of results on page n+1 is <= 50% of the page size, we return the results as part of the request.  If any of the above conditions fail (there is no next page, or the next page is >50% the size of a regular page), we don’t do anything special – we just return the regular sized page.

It’s features like this that are almost completely transparent to the end user, but make it that much better of a user experience.

Chasing the Rabbit

Sometimes, when working on something, you start digging into a particular technical issue.  The more you dig into it, the more it leads you away from your original goal.  I like to call this “chasing the rabbit”.  If you chase a rabbit through the woods, and only keep your eyes on the rabbit, you’ll eventually find yourself lost in the woods.

A few months back I was working on pylons.info – a website I was putting together for finding local events.  One feature of the site allows a user to post new events.  Part of adding a new event is setting the date and time of when the event starts and ends.  In trying to find a good solution, I think I must have investigated at least a dozen or so different date-time pickers for JavaScript.  Some only allowed a user to pick a date.  Others only allowed a user to pick a time.  Some had dependencies on other large libraries (like Angular).  All this digging into a single part of a single feature had me entirely consumed.  I lost sight of the big picture – getting the site up and running.

It’s easy to lose sight of the big picture when you are “chasing the rabbit”.