First step usually involves a whiteboard and/or pen-and-paper notes for developing the overall design, data structures and algorithms. Then I'll use hierarchical note taking to sketch out the data structures and algorithms in what amounts to pseudo-code. During that step, I'm constantly looking through any existing source code and repeatedly iterating to make sure all cases are handled.
Then the fun part of walking through those notes and coding out each individual step one by one. That will typically take anywhere from 2-8 hours without touching the compiler (though sometimes, if the changes are incremental, I'll compile occasionally to check for typos). I'll queue up a few albums and/or mixes to help focus and just sort of disappear from the rest of the world.
I'm at the opposite extreme: I code in Lisp, so design and coding are interleaved with a cycle time measured in minutes or seconds. The compiler is my collaborator throughout, checking my work at every step.
[UPDATE] Downvotes? Seriously? Why?
I don't think that 'in the zone'-programming has to produce bad code, though (if that's what you are saying). I'd argue that it depends on what gives you a reward. If you take pride in your code then you will find it rewarding to write tests and decent comments etc., and more importantly make a habit of doing so. A lot of people who write bad code think that they can get away with it because they are 'smart'. These same people then spend a ton of time trying to find bugs.
It sounds like your colleague is 'finishing' features by accumulating tech debt. While this may impress non-technical management, from my experience, it wouldn't make it into a high-quality production code base.
From people I've worked with, it seems like most people go through phases of extreme productivity ('being in the zone'). The code quality may suffer somewhat during those times, but they don't throw all good practice out of the window (not compiling for days, no tests?!?).
A variation of this can be interesting to do as an exercise (in my case, a single-program exercise in school). Keep your problem simple, maybe data parsing or the like. Being in a really bad mood when you start can help.
Cowboy code. Compile. Test. At any failure, delete everything and start fresh.
By the time you code a first-time-working copy you'll probably have dropped a huge amount of unnecessary junk from your code, possibly changed approaches multiple times, and maybe found some patterns in your coding that you'd like to do away with. Nuking those code files can be surprisingly cathartic as well.
Not sure how this would really go in a modern IDE or code editor though....
* New-ModuleFile to create a new module file.
* Insert-TextIntoFile gives a way to specify New-Function, New-Parameter, and any other Powershell function or Cmdlet parenthetically, so adding a function to a module file is a one-liner. I use the alias "instxt".
* New-Function provides the function punctuation and my closing flags.
* New-FunctionStatement (alias NFS) helps lay out any conditional function, including placing punctuation (brackets) and closing flags.
- Instead of typing all the brackets and parenthesis and variable names, I can type "nfs if text -scriptblock '$text' -else '"No Text"'"
* New-Parameter helps you specify Parameters and their numerous variables, such as Type, Mandatory, Position in the arguments list, Validate-Set List, and From Pipeline.
- Pipeline is a Powershell way of chaining Foreach in an ad-hoc fashion.
* Get-History returns previous commands as objects; these go nicely into "instxt".
- A common workflow is to create the function in the "instxt" statement, and have New-Parameter and Get-History as arguments.
- This way, a previously-tested function can be dropped straight into a module as a new function, with parameters already set up. From there, the module can be simply reloaded, and that function used as any loaded function.
The agility this gives is almost indescribable, and I wish I had a better way to demonstrate. Suggestions?
But in a team, I would much rather have someone practice TDD than be perceived as more productive. Your code will stand the test of time and be easier for others to work with, which will cost less down the line (maintainability cost + fixing bugs cost, inevitable and a huge time sink without tests). I am now trying to think in a TDD manner and it's frustratingly slower, but ultimately a lot less stressful when I have something I can point to and objectively say it fits the requirements / business rules.
Example: When programming in haskell, I just write the types (not always) and undefined most things and only then I start implementing. Whenever I make a new function, it gets composed by a bunch of other functions that are not yet implemented (undefined's) and eventually this converges.
Refactoring is then based on equality principles in my head. Yeah, it fails sometimes, but that's why pure functions and type safety feels so important sometimes.
ttd forces you into a pattern where your brain doesn't have to think for itself and waits for the computer to tell you if what you did was right.
ttd provides good training wheels. I think it works best when someone else has defined the requirements but is not the best choice if the requirements will continue to change or if people are not exactly sure of the outcome before the code writing starts.
i don't think that being high productivity prevents you from writing unit tests or doing tdd. you just do tdd with higher productivity.
I've met a few programmers in my career who were able to write a huge amount of code doing wonderful things without testing at all. One guy I think of would spend days coding without even trying to compile his code and apparently, except for minor typos he could quickly fix, his code was working when he decided to compile and test it. He impressed bosses and colleagues with amazing features developed in a very short time but, on the other hand, nobody on the team was able to maintain his code. This was explicitly stated and accepted by team members, we knew we couldn't maintain his code but we were ready to accept it given the productivity of the guy. It was a trade-off.
This way of working is completely alien to me. I can't think things in my head out of nothing and write working code. I need to start building something and get feedback from the computer to go to the next step. That's why when I was introduced to TDD it immediately made a lot of sense to me. It matched the way I was already operating. If I didn't have this workflow I think I would be unable to write even mildly complex code.
It's interesting how people can operate differently. In a way I'm a bit jealous of those "zone" programmers who can produce amazing things very quickly. But, on the other hand, I can see that I'm also useful because companies hire me and want to keep me. I've seen many times people taking over my code, maintain it and develop it further. I've even been explicitly told a few times that my code was very easy to understand and maintain. Seeing people taking over my code and develop it further is one of the most satisfying things in my work.