Handling destructive updates in applications

One of the early lessons I learned after developing my first few web apps was to never actually delete records from a database. Even when the user clicked the “Delete” button it was almost always better to archive the data for undo or restore actions later then to actually delete the data. Storage space (even at the time) was cheap compared to the user’s data. Unless there was a good reason it was usually better to archive data then to delete it.

Over a decade later the vast majority of apps that I regularly use all provide undo or roll back functionality for deletes. Implementing this functionality is relatively easy (usually just a bit flag on a record) and a huge win for users.

A tougher problem to solve – and one that still gets skipped all too often – is the ability to undo destructive updates. The most robust way to handle this is to implement a versioning system. Wikis and most modern publishing systems (like Wordpress) do a this really, really well. Allowing users to rollback to easily compare with and roll back to previous versions of a text. The problem is that a good versioning system is not as trivial to implement as simply flipping a bit flag to undo a delete is.

As a result of this difficulty it’s common to see versioning on large text fields but completely ignored for most pages that control settings etc. (completely guilty of this myself). This is unfortunate.

I would advocate for meeting the users halfway: For areas where traditional versioning seems overkill (settings pages particularly) we can log all changes and make those logs available to users in some format. Even if a basic CSV download of the version history is provided I think this would be enough for 80% of the use cases and is vastly superior to nothing is the current standard for these types of pages.

Dorodango code

One of the first applications I wrote as a fledgling programmer was a threaded BBS in 1999. It was heavily used by a small group of people for a number of years and I continuously tweaked and improved it. Running on Classic ASP with an Access backend, performance was always always a problem and with each tweak I would make it a little faster and learn a little bit more about each layer of the stack.

The greatest technical lesson I learned was that trips on the wire are really, really expensive. Sending a single query to the database and sorting and filtering records using VBScript was an order of magnitude faster then relying on multiple database queries to render the threading. I eventually further improved on this by re-generating the board as static html on each post. The performance was incredible, but also resulted in some tricky IO locking bugs.

I still consider it to be one of the most satisfying pieces of software I’ve ever written. In addition to the joy of creating something useful, I had a real sense of pride and accomplishment in the code itself.

Dorodango

Dorodango is a Japanese pastime/art form where mud balls are polished to an incredible shine. It may not be a terribly practical activity, but it can apparently be a really satisfying one.

We all sometimes have to throw code together under a tight deadlines that will be pushed into production shortly afterwards. It’s not a fun experience and it can be draining.

So I have dorodango code. Code I can work on and feel revitalized when I’ve had to work on a particularly draining codebase (primarily legacy software). Like polishing mud balls the work doesn’t have to further any other purpose, it just needs to be something you find joy and satisfaction in. The code can be something to scratch a personal itch or a professional pet project.

Whether it is squeezing a few extra milliseconds of performance out of the application or polishing the design a little more, working on these applications is deeply satisfying and fun.

So do you have a dorodango application? Something you keep polishing and improving and feel personally proud showcase and talk about as a developer? Do you feel good talking about that application? Do you get excited talking about it?

git religion

I was raised in an SVN household and later converted to Microsoft’s TFS. It was a conversion of convenience and I never developed the zeal of a true believer. I would listen to the followers of other systems proselytize their way, but never gave their way more than a cursory investigation.

Then these git guys started showing up.

They were different. They were weird. They didn’t want to talk about how git was better than SVN or TFS. They just wanted to talk about how much they loved git, and how much git loved them.

Intrigued by these crazy git prophets, I decided to embark on some source control tourism. I was going to try them all out. I was going to go back to the source control of my childhood (SVN), join these git guys for a while, finally get around to dropping by the Mercurial temple, and even go check out those Bazaar and Perforce sects I had heard about.

Two years later, I emerged a distributed source control convert who worships in the house of git.

Why I became a distributed source control convert

I am git disciple, but my true conversion was to the way of distributed source control systems. Mercurial, the other popular distributed option, is also a fantastic tool. Both of these tools essentially worship the same gods, but differ on how certain tenets of the faith should be followed. I am going to talk about git, but most of the points apply to Mercurial as well.

1. Git asks for little

Git doesn’t ask you to setup any special places of worship. You can practice git alone in your home, with a group, or in the beautiful GitHub cathedral. Git doesn’t care.

TFS and Perforce – on the opposite side of the spectrum – have very exacting requirements for their places of worship, which are extremely expensive and tedious to construct. SVN is certainly better then TFS or Perforce in this respect, but the setup and maintenance of a separate place of worship seems needlessly complex after git.

2. Git forgives much

Git is very forgiving. It is pretty hard to irreversibly screw something up in git. Even if you are tempted to try something insane (like rewriting history) backing up git is as simple as copying your .git directory elsewhere.

This contrasts starkly with its centralized predecessors where backing up and restoring repositories is not trivial and mistakes are not easily forgiven. I am very wary of trying potentially destructive operations in these systems and as a result tend not to explore them as readily as I do git.

This forgiving nature removed any dread or trepidation I felt exploring the system and made git a lot of fun to learn.

3. Git sees all

IDEs like Visual Studio and Xcode have the disconcerting habit of asking if I want to save changes even if I am pretty sure I didn’t make any changes. Git restored my sense of sanity on these occasions. A simple status lets me know which files have changes and a quick diff shows exactly what changed.

The centralized brotherhood requires me to inform them when I want to check out a specific file and appear incredulous when I try to get them to understand that I’m not sure what changed.

IDE plugins for the centralized systems automate this notification, but should you edit a file outside the IDE and fail to inform central control, your change will not get picked up. As a result there is always an unsettling feeling in the back of your mind that there may be an orphaned change floating around out there.

Git’s omniscience gives you a warm fuzzy feeling that all is well and all changes are accounted for.

4. Git believes in many paths

Branching. The concept is supported by the centralized systems, but implemented as though branching is a serious and weighty decision that requires pre-branching counseling and a decision that should not be taken lightly. As a result, branching in these systems tends to be reserved for major changes.

Git treats branching like breathing. After you use git for a while branching will become an automatic reflex. Branching is so easy with these tools that it changed the way I actually write code.

Summary

Git is a wonderfully simple, flexible, and forgiving tool that just works. At first, to be honest, it’s a bit weird. Centralized systems are a lot easier to grok and the git merge model looks like a mess from the outside. But then you realize: development in the real world is a mess, and git works with that instead of against it.

The caveat of a novice

I can’t claim more than a novice’s understanding of all of the source control systems I tried on my trip. There might be some magical level of proficiency you can reach with the tool where the experience is transcended into bliss (I keep hearing that’s what finally mastering emacs is like). If it exists for TFS, SVN, or Perforce, I never reached it.

The Jeff Atwood and Scott Hanselman motivations

In the pantheon of programmers there are gods like Anders Heilsberg and John Resig — whose abilities and talents are beyond the reach of mortal coders — and there are the Heroes: coders whose talents may be within mortal comprehension but whose feats are the stuff of legend.

Jeff Atwood and Scott Hanselman are two of my favorite heroic programmers. Both are extremely passionate about their craft and are driven to continuously improve themselves as developers.

The primary drive for their respective passions however appears to be subtly different.

The joy motivation (this is neat!)

Atwood appears to be primarily driven by the joy of what he does. There is constant sense of awe and wonder in his posts and podcasts, and it is immensely infectious.

The strength of this approach is the seemingly unlimited font of energy and excitement he taps into. He is as passionately excited about the user experience as he is about the code.

The joy motivation prevents burnout and keeps a level of energy in the pursuit that is hard to match. This is also the weakness of the joy driven developer. Purely pursuing joy may sometimes look like a cat chasing a laser beam to outsiders: chaotic and unorganized. If your joy manages to take you where you need to go, fantastic. But if not, you may not be paying enough attention to other subjects (say your code’s security) as you need to.

The guilt motivation (why aren’t we better developers?)

Hanselman’s motivation sometimes appears to be a guilt that he isn’t a better programmer. He relentlessly strives for perfection in his craft and as a result often achieves a level of excellence that is unmatched by many.

He certainly exudes joy as well (listening to him and Jeff discuss hardware and movies on this podcast is an experience in joy and excitement in itself), but what seems to drive his passion as a developer is a professional craftman’s guilt and desire to be better.

The strengths of this approach is that you stay on task and end up being a much better professional developer. The two main weaknesses are that either you will burn out quickly or that you will get tunnel vision. Some of Hanselman’s views (like 100% unit test coverage) in my mind start allowing perfect to become the enemy of good. If you become too focused on the guilt of what you have not accomplished you may not be able to take a good look at the landscape and pace yourself on the journey to becoming a better developer.

You need both motivations

All developer’s, to some degree, possess both motivations.

Without finding the joy in what we do we would burn out rather quickly. The joy is why we enjoy building our own machines, learning a new language, or tackling the difficult problems.

Without that professional guilt we might half-ass important, but less exciting, aspects of our code (like security). You need both motivations if you’re going to be a developer for a long time, but most developers do have a primary motivation.

My primary motivation

I tend to fall into Jeff’s camp (that’s neat!), but acknowledge that cultivating some professional guilt will make me a better developer.

Which is your primary motivation?