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.
Tuesday, July 6, 2010
Saturday, July 3, 2010
The 4 moves of TDD
The three laws of TDD are:
Writing a test Writing production code Refactoring a test Refactoring production code
- 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:
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.
Subscribe to:
Posts (Atom)