You should think about what you're going to do before you jump into the code.
Otherwise, you're likely to find that you just wrote some impressive-looking code that does nothing useful, and be forced to hack it up, or scrap it and start over.
It's also good to think about what you've done:
This isn't meant to imply that you must do all
these things. Rather, any one of them would be considered "thinking about what you're doing." Thus, each one of these approaches, including ExtremeProgramming
, encourages people to think about what they're doing. The alternative is hacking.
This also serves as evidence that ExtremeProgramming
is not hacking. And indeed, it may have more in common with conventional methodologies than you realize - repeatable success, for instance.
On doing a CodeReview before UnitTesting:
I don't understand - under what circumstances is it more effective to use expensive, inaccurate human time to review code rather than inexpensive, accurate machine time to test it? When I could only get one shot at the machine per day, this notion might have made sense. When does it still make sense in today's environment?
In a traditional development environment, code reviews have been shown to find more errors than ad-hoc (un-automated, non-regression) testing. And code reviews tend to find a different class of errors than conventional testing. This would suggest that doing both would be a good thing. Possibly, you are already doing both, Ron: What's the 2nd person in PairProgramming
doing, if not looking at what the person at the keyboard is doing, watching for errors and making comments on how to improve it? So I'd be inclined to suggest that PairProgramming
could also be called ContinuousCodeReview?
. Now that's taking the CodeReview to extremes!
The main argument for code review before ad-hoc testing is psychological: after doing ad-hoc testing for hours and fixing every bug they can find, a developer won't be receptive to refactoring their code for slight improvements in some abstract subjective concept of "quality". Such changes are more likely to introduce real, tangible bugs, and will certainly require an even more tedious repetition of the long hours of ad-hoc testing. In ExtremeProgramming
, these would not be issues, because UnitTest
s eliminate the testing problems, and PairProgramming
reviewed the code before it was even compiled the first time (...ContinuousCodeReview? ;-)
Sounds like review is a poor patch for ad-hoc testing. Automated testing would be better. Therefore, don't do code reviews, do automated testing. Duh. -- pm3-01a2-port05.dundee.net
Code reviews find bugs that ad-hoc testing misses. But would automated regression UnitTest
s find those bugs? -- JeffGrigg
By definition, TestFirstDesign
eliminates bugs. The UnitTest
specifies what the code needs to do and then the code is written to satisfy the test. There are limited sets of errors that TestFirstDesign
may not catch, such as uninitialized variables, buffer overruns, and memory leaks. Except for beginning programmers, I have rarely seen conventional Code Reviews catch these problems, usually far more false problems are "identified".
With Code Reviews, a large amount of code needs to be reviewed to make it cost-effective. If a reasonably competent programmer who has spent considerable time writing the code missed something in this mass, how is it likely that other peers are going to be able to find it in a relatively short time-frame? Contrast that with PairProgramming
, where a second person reviews the code line by line as it is written.
Also note that regression testing is appropriate only during refactoring. It is during this phase that unexpected couplings can occur in code. The more refactoring done between regression tests, the greater the risk. Doing a massive refactoring, then having a code review, followed by a massive testing effort is a recipe for disaster.
Code Reviews result in batch mode development. Large blocks of code, well beyond the understanding of a single person, get written all at once. Finding errors in this haystack is beyond the ability of the individual coder; it is even more difficult for an outsider to do in a few short hours.
Code reviews are dealing with different issues from those dealt with by unit testing. I can write a class and a unit test for it, and it's 1000 lines of class and 3000 lines of UT and still unmaintainable. Code Review (whether continuous as per PP or outside) should make this impossible. Some of the code review practices can be automated as well - even made a part of the build (and be able to fail the build if required). -- VladEnder
On writing PseudoCode before writing the code itself:
Ditto this one. In what languages does it still make sense to [formally] write pseudocode? Sure, write a couple of quick notes on a card, but really pseudocode each algorithm? And with objects, what does this even mean? Pseudocode a couple of methods on five or ten classes? -- RonJeffries
Ron - I believe it still makes sense to write pseudocode if you are writing in 80X86 Assembler. :) -- KyleBrown
It's actually useful when writing something in assembler, but for other languages I just don't see the point. IMHO, it's just a waste of time. -- PatrikPersson?
PseudoCode is easier to modify than real code. It's basically a mini-design. And it's almost always easier to modify things at the design stage than at the code stage (visualize ripping out a wall vs changing a line on the blueprint). One nice side-effect of PseudoCode is well-commented code. In my opinion, PseudoCode makes sense for
all languages, and will continue to do so.
Ok, I visualized ripping out a wall versus changing a line on the blueprint. Now could you explain what this has to do with writing pseudocode? If real code is that
much more costly for you to change than pseudocode, that's an excellent sign that you should be writing it in a different language. (Or, I suppose, that you're a really bad programmer, but I choose to assume that's not so.)
Why is writing pseudo-code "thinking" while writing actual code is not? If I am going to write code, why not write real code rather than pseudo-code?
One exception here which, as a Smalltalker, you don't have to live with, is to use a dynamically-typed language to prototype before rewriting in a statically-typed language. For example, on one project I sneaked Python in as "executable pseudo-code" before porting to C++. Of course, we didn't bother porting in the end (I believe this used to be a technique for getting Smalltalk through the door). -- SteveFreeman
Indeed. I'd not have whined had the original author said "implement a prototype" instead of "write pseudocode". -- RonJeffries
The initial argument seems to be based on a false premise - that when you're coding, you're not thinking. XP addresses this explicitly - with UnitTest
s before the code is written, and if you RefactorMercilessly
, you can do both. You won't have something useless, because you wrote it to pass the UnitTest
s. You won't have impressive looking code that does nothing useful, because you DoTheSimplestThingThatCouldPossiblyWork
. And XP isn't the only way to ThinkAsYouCode
Conventional methodologies don't seem to put much "thinking" into the process of writing code: The coder's responsibility is to translate detailed written specifications into code; "ideally" a semi-mechanical process. So, with a conventional methodology, "thinking" has to be added before or after the coding process, as an additional technique, to make things come out right. ExtremeProgramming
, however, appears to make reflection an integral part of the programming process, with UnitTest
s and PairProgramming
, and then follows with RefactorMercilessly
- an even deeper form of thinking.
Don't write pseudocode. Write real code. It actually does something useful.
Pseudocode, graphic diagrams, and other design tools are languages for writing computer programs. But they are terrible languages. Typically, you can't test, compile, or even generate a working prototype (let alone a shippable product!).
Sometimes, you need design, hand waving, or whatever. You should do this with the real computer language. This is because language choice affects design.
I agree with the above statements. The way I usually do this is I first write a bean shell program (which is just a script) that tests my logic - once I see expected results, I translate this into a real program. Recently, I wanted several specific functions (maxHop(diameter of a graph) in a fabric, to find if a fabric is a mesh etc.) written on a fibre switch fabric (this is like a non-directional graph). So I write each algorithm as one bean shell program and test the logic and then move it to the real objects. The advantage I found in doing so is that I concentrated only on the logic part. Once I translated the scripts into real classes, it generated requirements for the real object model.
On drawing detailed design diagrams before writing the code:
For what languages and what kinds of problems do detailed design diagrams actually help? Yes, of course I know that people do recommend this ... but is there any data to indicate when it helps and how much? -- RonJeffries
My answer to Ron's question above has to do with DesigningVsModeling
. You take a drawing of the Model into the room full of business and database and other experts. They critique it to see whether it contains any FalseAssertionsAndUnattractiveRestrictions
regarding their business. This they can do. -- AlistairCockburn
- Do the business people actually understand the models as well as they understand running software?
- Is creating the models really significantly easier than creating the software?
- Does the model represent the predicted software well enough to be evaluated?
The problem is, most of the time, that these formal designs and models just delay the moment of truth when someone sits down and tries the software. The best way to reduce risk is to get the running software in front of people as soon as possible. The sooner we move from the realm of prediction to the realm of reality, the better. -- AnonymousDonor
Yes, Yes and Yes to the questions when done half-decently, and also Yes to the paragraph that follows the questions. -- AlistairCockburn
My question would be how do you verify that your model is "as simple as possible" and still correct. Sometimes, business people tend to go into irrelevant details (irrelevant = 1 case a year which is cheaper to deal with in paper rather than build SW to do it) even more than we do. While coding a feature to death is also possible, it's less likely as you're dealing with "real" stuff. The main advantage of "executable model/design" I see is that it's unambiguous and formally testable. I would still argue that knowing something about the bigger problem beforehand is helpful. It can build a system that works and is great for one user, but refactoring it for more concurrent users would be a major pain.
Why is this called "Think, then code"? Coding is thinking about details while design is not. You need to focus on different levels at a time. If you only code, you don't do all the thinking you should. -- Per Lundholm