Wednesday, July 7, 2010

Over design and the “but” exercise

Do you suffer from “over-design”? Do you even know if you over design? Is there any way you might be able to self assess? (Are you asking, "What is this "over-design" of which you speak?")

Here’s an exercise you can try on yourself (you can also try this with a team, but I’ll have more to say about that below).

The exercise seems simple. Count the number of times you say “but” in a day. Simply track it. Don’t do anything with the number, just count it. That’s it. You can get a bit more sophisticated and add other words and expression such as:
  • However
  • That won’t work
  • ... because

You might want to consider working up to that.

Warning, you might be thinking it as well. Count those if you can. Or, maybe work up to those as well.

Ultimately, what you are trying to do is simply observe the number of times throughout the day you reject an idea. That’s often what you do when you use the word but.

In an of itself, rejecting an idea is not a problem. Even a pattern of rejection is not a pattern. Observations like this are data. You might try to find patterns or correlations such as:
  • I tend to reject Andy more than I reject Mary
  • I seem to reject ideas in the morning or during lunch
  • Initially I reject ideas from my wife that require me to do work. I tend to come around (this is one of my patterns).

Once you discover those patterns, you might ask yourself if they fit for you. If they do, great. Maybe you got a little personal understanding. You probably became more keenly aware of how often you tend to reject ideas.

You can take this one step further to find times when you might be rejection and idea and are not even aware of doing it. Try the exercise again. This time, rather than counting the number of times, instead make the observation that you are saying “but” (or some other such expression). As soon as you do, and this is key, try to figure out where in your body you hold that feeling. It might be in your stance, hands on your waist. It could be in your celiac plexus, shoulders or your neck. If you are not used to making these kinds of observations, it will probably take many tries before you notice. You've probably become so used to manifesting a physical response to a given situation that it’s like fish in water.

As you become able to make these observations, then next thing to look for is patterns. Maybe:
  • When I talk to women and reject their ideas, I stand in a particular way
  • I tend to get hungry when I have to say no

As with the previous exercise, it’s data. Does the habit fit? If so, great. If not, then maybe try to find a way to break the habit. What you are doing is turing unconscious decisions or habituated behaviors, into conscious ones. You are giving yourself more choice. Really, you’re taking control of yourself from patterns you’ve picked up over the years.

There are several ways to do so. You might simply:
  • Smile in that situation
  • Breath (through the nose into the pit of the stomach)
  • Put a micro-bend in your knees
  • Tapping (the NLP variety, though if you have the shoes...)

The interesting thing is that making these kinds of observations will mostly likely result in some kind of change. Awareness tends to lead to change. If a particular behavior fits, then the observation will not likely change a given behavior. However, it might still make you aware and give you other options.

What about trying this in teams?

Danger, danger.

It’s certainly OK to try this with a group. One thing I’d be concerned about is applying a metric to the result of the count. For example:
Brett is the most negative, I counted how often he said “but” and it was the highest

This is a personal exercise. It’s easy for it to turn into a competition. While you might ask someone to help you notice something you are doing, it’s easy to turn a simple exercise like this into an ongoing battle.

How does this have anything to do with over design?

Have you ever noticed that moving from the design of a solution to the design of a framework is made with one “...but what about this...” at a time?

I’m certainly guilty of this.

On the one hand, implementing with too little context can lead to a myopic design. On the other hand, considering too much context often leads to over generalization (framework-itis). There’s certainly a balance somewhere in there.

Over design is a problem when you’ve designed for A but you really needed a design for B. Over design typically is more like, "I’ve introduced flexibility for A, B, C, D, E, F, G but you needed a subset of F".

How can this “but” exercise help?

When you are working through requirements on your way to design, simply track how often you ask the questions in a form such as “...yes, but what about...”. Every time you do, a kitten dies. Are you missing the forrest due to all of the trees? I've noticed this in myself and I think it's a pretty common characteristic in developers.

Extreme Test Driven Development is another way you can avoid over-design at the possible expense of myopic design. As with most things, there are many good paths somewhere in the middle.

In any case, if you think you might be a culprit of over design, or maybe even being a bit of a Negative Nancy, maybe this exercise could help you determine patterns driving your behavior. With that information, you might consider trying on different patterns to see if they fit better.

Tuesday, July 6, 2010

What does it mean to be an ENFP: Part 1, E

Extraverted, that's me. Yes I talk quite a bit, but that's not nearly enough to know if someone is an Extravert or an introvert. I personally know several introverts who, once they start talking, won't be quiet long enough for me to get a word in edgewise.

As an extravert, I draw energy from engaging and talking - most of the time. More importantly, I think by talking. I form ideas through, primarily, language. Even if I'm being quiet, my inner dialog is in the form of a conversation between myself and either projections of people I know or made up archetypes. There's nearly always an inner dialog going on in my head. Often even when I'm talking.

The ideas I form also appear outside of myself. When I'm in some kind of technical discussion, I often am forming a visual model (often in UML, a bit embarrassing, I know) that I can almost see in front of me. Typically this model is around 18 inches away from me, but it can be larger and more distant depending on the size of the subject.

How do I know it's 18 inches? Well I point to it. It's a fairly regular occurrence for me to explain to a class that I'm pointing to a model that is right in front of me. I describe its parts and even show them where those parts are relatie to my position. It's strange, however, if I move. Often, when I move, the model stays put. Sometimes it tags along, but I've often made a physical reference (e.g., pointed to) a model that only existed in my head that's in another location in the room and is where I was when I created that model.

Of course I don't actually see a model. Instead, I have an idea of a model in my head, I'm a visual thinker, my visual cortex is engaged as if I were interacting with something outside of myself, so the experience is that there is a model outside of me.

So like language, visual processing also happens outside of me.

From my interactions with introverts, their experience is entirely different. Some think in terms of colors and sound, or at least that's as much as I can attempt to understand from their description of their internal process.

One thing is certain, typically introverts speak well formed, complete ideas. Ask them a question they have not answered and they could go silent. It's not that they are ignoring you. It's that they are processing it.

Do the same thing with me and I start talking. I might ask clarifying questions, I might go self-referential and describe the approach I'm taking, the categories of characteristics I'm interesting in looking into, etc. Then I might get back to asking questions, often onces I'd answer myself, and eventually I might get to an understanding.

Add to the mix that I talk fast, and sometimes I overwhelm (irritate, get on the nerves of) my introverted friends. Hell, sometimes I even get on my own nerves. And other, stronger, extraverts really get on my nerves!

That's one dimension of a model of me.

Remember:
- everything is a model
- all models are wrong
- some have value

Off to bed for a few hours until I have to get up and drive in Tel Aviv traffic.

Saturday, July 3, 2010

The 4 moves of TDD

The three laws of TDD are:

  • Write no production code without a failing test
  • Write just enough of a test to fail
  • Write just enough production code to get the test to pass

This list doesn't include refactoring, which is typically an assumed activity. In fact, some people refer to these rules as "red, green, refactor". An even older version of this, from the Smalltalk community, is Red, Green, Blue.

So there are two kinds of code: test & production. There are two kinds of activity: writing & refactoring. Interestingly, at one level it is all code. The thing that distinguishes both sets is intent.

The intent of a test is to demonstrate or maybe specify behavior. The intent of production code is to implement (hopefully) business-relevant functionality.

The intent of writing code is creation. The intent of refactoring code is to change (hopefully improve) its structure without changing its behavior (this is oversimplified but essentially correct).

If you mix those combinations you have:
  • Writing a test
  • Writing production code
  • Refactoring a test
  • Refactoring production code
  • An important behavior to practice is doing only one of these at a time. That is, when you are writing tests, don't also write production code. Sure, you might use tools to stub out missing methods and classes, but the heart of what you are doing is writing a test. Finish that train of thought before focusing on writing production code.

    On the other hand, if you are refactoring production code, do just that. Don't change tests at the same time, try to only do one refactoring at a time, etc.

    Why?

    First an analogy that almost always misses since most developers don't additionally rock climb.

    When rock climbing, a good general bit of advice is to only move one contact point at a time. If you just consider two hands and two feet, that suggests that if, for example, you move your right hand, then leave your left hand and both feet in place.

    This gives you stability, a chance to easily recover by simply moving the most recent appendage back in place and, when the inevitable happens, another appendage slips, you have a better chance of not eating rock face. If you move more than one thing at a time, you are in more danger because you've taken a risky action and reduced the number of points of contact, or stability.

    Will you sometimes move multiple appendages? Sure. But not as a habit. Sometimes you need to take risks. The rock face may not always offer up movement patterns that make applying this recommendation possible. Since you know the environment will occasionally work against you, you need to maintain some slack.

    Practicing Test Driven Development is similar. If you change production code and tests at the same time, what happens if a test fails? What is wrong? The production code, the test, both, neither? An even more subtle problem is that tests pass but the test is fragile or heavily implementation-dependent. While not necessarily an immediate threat, it represents design debt that will eventually cause problems. (This also happens frequently when tests are written after the production code as it's seductively easy to write tests that exercise code, expressing the production's code implementation but fundamentally hiding the intent.)

    Notice, if you had only refactored code, then you know the problem is in one place. When you change both, the problem space actually goes from 1 to 3 (4 if you allow for neither). Furthermore, if you are changing both production and test code at the same time and you get to a point where you've entered a bottomless pit, you'll end up throwing away more work if you choose to restore from the repository.

    Are there going to be times when you change both? Sure. Sometimes you may not see a clear path that gives you the option to do only one thing at a given time. Sometimes the tests and code will work against you. Often, you'll be working in a legacy code base where there are no tests. Given that the environment will occasionally (or frequently) work against you, you need to maintain some slack.

    Essentially, be focused on a single goal at any given time: write a test. then get it to pass. clean up production code & keep the tests first unchanging and then passing.

    I find that this is a hard thing both to learn and to apply. I frequently jump ahead of myself. Unfortunately I'm "lucky" enough when I do jump ahead that when I fail, I thoroughly fall flat on my face.

    This approach is contextual (aren't they all?). Every time you start working on code, you'll be faced with these four possibilities. Each time you are, you need to figure out what is the most important thing in the moment, and do that one thing. Once you've taken care of the most important thing, you may have just promoted the second most important thing to first place. Even so, reassess. What is the most important thing now? Do that.

    Good luck trying to apply this idea to your development work. I'm interesting in hearing about it.