Friday, December 5, 2014

Are You an Over-Abstractor or an Under-Abstractor?

I really like to teach people about different techniques of abstraction. If you don't believe me, just check my website: Interfaces, Dependency Injection, Design Patterns, and even the BackgroundWorker Component (and also my courses on Pluralsight).

One of the reasons that I talk about these particular topics is that they are things that took me a really long time to understand myself, so I like to help people take a short-cut to understanding. But that leads to a problem. Once we learn about them, we might want to use them everywhere, and we end up building a complex mess that's hard to maintain.

But over-abstraction is not our only problem. If we have too little abstraction, then our applications can be rigid and hard to maintain. So as developers, our goal is to find the sweet spot right in the middle. This is why I came up with "Abstract Art: Getting Things 'Just Right'" (which I give as a live presentation and as a course on Pluralsight). We're really looking to follow the Goldilocks Principle when it comes to abstraction: not too much, not too little, but "just right".

The Goldilocks Principle (from the presentation slides)

Observing Developers
So why do we, as developers, have a problem getting abstraction right? There are a number of factors, but the biggest one has to do with our natural tendencies. I'm not sure if anyone has done an official study on this, but I formed this opinion based on my observations of developers that I've worked with (and also by reflecting on myself).

The premise is that every developer has a default state as either an over-abstractor or an under-abstractor. Over-abstractors like to build stuff and think about all the possible uses of an application in the future. This may lead to overly complex implementations for features that will probably never get used. Under-abstractors like to keep things simple. This may lead to things like global variables, tightly-coupled components, and "god classes" with all sorts of functionality.

This is just our "default state" -- meaning, without any external influences, we lean one way or the other. But as we gain experience as developers, we run into difficulties with our default state and so we go in the other direction. This often results in us swinging too far, and we end up correcting back the other way.

The Pendulum Effect (from the Pluralsight course)

Eventually, we figure out the dangers of both over-abstraction and under-abstraction through trial-and-error. The main reason I wrote my presentation and Pluralsight course is to give people some best practices so they can skip some of these bad experiences.

One Group is Not Better Than the Other
The first time I gave this presentation, I ran into a bit of a problem: one of the attendees thought that I was promoting one group over the other -- for example saying that under-abstraction is better than over-abstraction. And that is definitely *not* the case.

Both groups have problems. With too much abstraction, we end up with code that is overly-complex, difficult to debug, and can cause frustration in people who are not intimately familiar with the code (which may include the original developer 6 months later). Ultimately, the code is difficult to maintain.

With too little abstraction, we end up with code that is rigid. It is hard to find bugs and very difficult to test. Ultimately, the code is difficult to maintain.

So we have a common result: code that is difficult to maintain. What we need to do is figure out how to recognize our natural tendency so that we can watch for the warning signs and hopefully end up with abstractions that are "just right" for our application.

Do You Meet More Over-Abstractors or Under-Abstractors?
In my presentations, I would love to do an informal survey to see if the developers identify themselves as over-abstractors or under-abstractors. But because I want to be careful not to create "teams" in the room, I don't do that.

I've been curious if there are more over-abstractors or under-abstractors in our field (or if there's an even split). I've been able to make the case of both groups.

The Case for Over-Abstractors
The main reason I would think that there are more over-abstractors in our field is that what we do is all about problem solving. We are developers because we like to come up with creative solutions and then implement those solutions by building things.

And a big part of that is the building. We don't want to use code that someone else wrote; we want to write it ourselves. This is often referred to as the "not invented here" syndrome.

Another part of this is that we like to plan for the future. Sure, we could build a robot that fetches a soda from the refrigerator. But wouldn't it be cooler if the robot would also vacuum as it goes? (Yeah, I know, we already have a vacuum cleaner that works well, but it will still be cool.) This is a fairly common mindset that we see in developers -- we are creative people.

Based on this, I might think that there are more over-abstractors in our industry.

The Case for Under-Abstractors
The main reason that I  would think there are more under-abstractors in our field is that there are a lot of developers who do not understand abstraction or what it is good for. As a young developer, I had a lot of trouble understanding why I would want to use interfaces in my code. I could tell they were important, but I couldn't find the right person to explain it to me. (This is one of the main reasons that I like to talk about Interfaces -- I don't want developers to go through the same struggle that I did.)

I come across a lot of developers who are like I was: they do not understand the basics of abstraction. I meet some of these developers when I'm helping them with their code; I meet some of these developers at my presentations. And my goal is to give them a better understanding of the topic while I have a chance to talk to them.

Based on this, I might think that there are more under-abstractors in our industry.

Any Ideas?
So, what are your thoughts? How do you identify yourself? Do you have more over-abstractors or under-abstractors where you work? What about the developers you meet at conferences or other events?

If you're not sure where you fall, you can check out the "Default State Quiz" that's part of my Pluralsight course.

By nature, I am an under-abstractor, but I've also swung into the over-abstraction world for a while. After my many years of experience, I like to think that I'm pretty well balanced, but I still have a tendency to lean toward my "default state" from time to time.

The first step to overcoming my default state was to recognize it. Since I've done that, I can now catch the times when I'm leaning too far toward under-abstraction. This gives me a chance to review some best practices to steer myself to a more balanced state.

Feel free to leave a comment with your thoughts (or drop me a note privately). I'm interested to hear what you think about the topic.

Happy Coding!

2 comments:

  1. I definitely do both. I over-abstract when deciding what the public API should look like, and I under-abstract when I implement it. :)

    Overall, though, I think I would tend to lean towards under-abstracting.

    As far as coworkers go, in my current position there's a lot of under-abstractors (with a couple notable exceptions); but with a previous employer there was a lot of over-abstraction (with a few exceptions). So my experience has been that they're pretty balanced.

    ReplyDelete
  2. In my experience, I usually worked more with under-abstractors, although there were a few notable over-abstractors as well (but definitely in a smaller number than under-abstractors).. I find myself in a kind of middle term, tending towards over-abstraction.. Ah! And we should not forget those who are under-abstractors for their own work, but, when it comes to judge other people's work, they quickly transform themselves into over-abstractors.. These are the worst!!

    Congrats for the article!
    André Lima

    ReplyDelete