Sunday, June 28, 2015

Favor Deletable Code Over Reusable Code

As problem solvers who work primarily in the medium of software, we're sold reusability throughout our careers (and even, likely, in our educations). We're told that if we just think ahead, if we put forth more effort, we can jump to a new plane of abstraction and achieve a solution that will be usable in the future to more quickly and easily solve a similar problem. Although this sounds pretty awesome in theory, I don't buy it in practice.

Arguments against optimizing for reuse

The first real problem I have with premature abstraction (in the hope of reuse) is just that -- it's premature. We'd like to think we know how our system ought to flex in the future, but we just don't. We're not fortune tellers.

We mean well. We build a more general solution than needed to solve a real problem
Our hope, thinking and intention is that future, similar problems will fit nicely into our "framework"
This sounds great, but there's a lot that can go wrong.

Firstly, what happens if our expanded solution doesn't "fully" solve the problem at hand?
Do we rewrite our more general solution to accommodate the actual problem? I find, generally, we don't. Instead we extend and further abstract our large solution to make it encompass the areas we missed. If we do re-write the general solution entirely, the previous general solution was effectively a time sink.

There's a fair amount of regression headache here as well. If I decided to extend my prior abstraction, then I have to do without breaking the parts that partially solved the problem to begin with. Also, assuming I still believed parts of the original abstraction to be valuable to future solutions, I would be required to also keep those from breaking.

 Secondly, there's a question I try to ask myself before I solve future problems: what will happen if this problem is a one-off? I usually have a few different answers to this
  • I will have wasted time building abstractions and tests that weren't actually needed
  • I will have obfuscated the intent of the solution with unnecessary abstraction, forcing future maintainers (myself included) to understand a more general problem than the one actually being solved, and
  • I will have introduced more actual code and tests to maintain (in many codebases this may be a drop in a bucket, but still, more is more)
The third and final consideration I have before thinking about reuse is really a few tightly-related questions, pertaining to reuse itself
  1. If a future problem is solvable by my abstraction, how will developers know to use it?
  2. If a future problem looks like it's solved by my abstraction, but it's actually a different problem, how will other developers know not to use my abstraction?
  3. What happens when a future problem is 90% solved by my abstraction? Is it flexible enough that someone else will be able to extend it to fit that extra 10%, while maintaining its integrity?
In my fairly short exposure to professional software development, I find the answers are something along the lines of
  1. They won't. They'll build another solution, and maybe their own abstraction framework to some degree.
  2. See 1, they probably won't ever see my abstraction or understand it. Although, I have seen a good bit of the "copy the original source, and tweak to fit" pattern applied in response to this question
  3. It won't be flexible enough. They'll build another solution.
Like I said, I'm a novice developer. So if you have solutions to these questions and problems, I'm eager to hear them!

Deletable code

Alright, honesty time. The above words are truly my take on some points made in Greg Young's the art of destroying software talk. At this point, I could spend paragraphs describing the value obtained by having code that, by nature, is easy to delete. But, to do so would be a waste of time when Greg has so well articulated the points. So, with that, I urge you to watch the linked talk, and rip my arguments to shreds in the comments section.

3 comments:

  1. Greg's talk is pretty irritating. I couldn't get through it. However, I like the basic idea of composing systems from microservices.

    To me, programming for reusability is all about designing APIs with an I'm-creating-a-service hat on. There is only a weak sense of having predicting the future. When I say "API", I mean this to include all interfaces between s/w components, even including command line interfaces.

    Most programmers create interfaces for today's task where they know who the client is going to be. In fact, it is often their code that will use the API. A programmer who seeks to create a service is designing the API for an unknown set of clients. The question is more about whether the API does a well-defined task and whether new features can be added without invalidating old client code. Although it always helps to examine future use-cases for the API, it is not necessary to do this exhaustively. This is really micro-platform-building.

    I think the "deletable code" meme is interesting but a bit too dramatic for my tastes. The issues are much simpler and straightforward.

    ReplyDelete
    Replies
    1. Thank you for the comment, those are fine points.

      Just out of curiosity, what about the talk irritates you?

      Delete
    2. The constant asking of rhetorical questions to the audience and the over-confident manner. It's as if he considers the audience as children to be instructed instead of peers.

      Delete