is an excellent intro, but it assumes that the reader isn't a novice. That's probably why it is so popular with professional programmers, one doesn't have to wade through pages of:
//This is a comment
/* This is a multi-line comment */
There are some issues in ExtremeProgramming
that might not be clear to the novice programmer, this is the place to discuss them or post links.
Proclaimed firstname.lastname@example.org from the mountaintops:
- Hello, I am making a small, tile-based game. Each tile is represented by a class called Tile and my game area is a two-dimensional arrays of Tile-objects. I'm just starting out with this project so I have some basic design questions. I am unsure how I should keep track of the valid directions from each tile and, given a valid direction, obtain the tile the player is moving to. I thought about have an 8-bit unsigned int as data member and let each bit correspond to one direction, starting from upper-left or something, but this doesn't give me the actual tile one will end if one travels in that direction. I could have 8 pointers for each Tile-object, but that seems crude somehow. Any suggestions on how to implement this are greatly appreciated.
All together now:
The first one means you should write lines of code into a UnitTest
you write production code to get tested. This rachets you along and makes
the code surprisingly easy to write, once you get the hang of it.
The second, per the book Refactoring
, means you should skip design
questions until after the tests pass. Then you should change the tested
code, in tiny steps, stopping to test after each little tweak. The
test-infected code will report any little mistake you make, as it happens.
The third item means code should be designed to be tested, the only way to
do this is via cycles of test-first and refactoring, and these together
will ramp your design up until it is clean, simple, extensible and robust.
The last item, UnitTestsDefined
, talks about how to build an alternate
project with an alternate 'main()'; this will call all the test functions,
which will contain lines like these:
cout << "Testing pieces move to new tiles..." << flush;
Piece aPiece (0,0);
assert (aPiece.getX() == 3);
assert (aPiece.getY() == 3);
... // more and more brainless obvious lines like this
cout << "okay" << endl;
... // more and more other test sets
cout << "All tests passed" << endl;
The rules are very simple. You write the first line here, compile, and run.
All tests pass. Then you write the second line. It can't compile, because
'Piece' does not exist yet. Add this, compile, and all tests pass.
Now add the line that calls 'move', and this member does not exist yet. Add
it, and put nothing in it. All tests pass.
Now add all the 'move' lines, then add the 'assert' line. This fails,
because 'move' did not really do anything. Make it do something, and get
this assertion to pass.
You must make 'move' do the simplest thing that could possibly make 'getX'
and 'getY' pass the assertion. Then, after you have more tests than this,
if you think of a better way to implement 'Piece's internals, upgrade to
Your question implies an unextreme mindset. You think that you must commit to
a design before you code. Nobody does it like this unless they want their
code to get very stale tangled & resistant to upgrades very soon, like
MS-DOS's kernel. If your code can always be upgraded easily then it will
Now good luck getting anyone in whatever courses you may be taking to tell
you any of this dreadfully obvious & simple stuff!