Old thread but since it has a sticky...
I tend to apply two principles that really have helped me in the past. The first is leverage test-driven development by writing a test for the application first, then the function skeletons so that the test at least compiles. For example that is overly simple I am simulating an address book (this is C++) so I write a simple test app; no actual code exists yet..
Code:
// test to look up address
int main(int argc, char *argv[])
{
int nRC = 0;
CMyAddressBook addressBook;
const char *someName = "John Jones";
string strResultingAddress;
// Attempt address lookup
if( addressBook.lookup(someName, &strResultingAddress))
{
// found it
cout << "Found address: " << strResultingAddress << endl;
}
else
{
// not found...
cout << "No address found" << endl;
}
return nRC;
}
Of course this will not compile; if for no other reason CMyAddressBook doesn't exist. However what this does is gives you exactly what you need in terms of API code. In this case, you need a single method for doing lookups. One advantage of this is that you only code as much API as you need and not more. Too many times beginners tend to overcode solutions and library, wasting time and money. This method reveals exactly what you need and not one line more.
However as written this will not compile so the next step in test-driven development is to write enough of the code so it will compile but not necessarily run. Thus you add a class to your code:
Code:
#include <map>
#include <string>
using namespace sd;
// class to do address lookups
class CMyAddressBook
{
private:
map<string, string> addresses;
public:
CMyAddressBook();
// lookup
bool lookup(string strKey, string *results);
};
Next I build out a skeletal version for the lookup method:
Code:
bool CMyAddressBook::lookup(string strKey, string &strResult)
{
bool bSuccess = false; // seed result with failure
return bSuccess;
}
The code now compiles but obviously doesn't work. This is where my use of comments come in. While this example is trivial in the extreme, I use comments n the function body to describe how the problem is solved:
Code:
bool CMyAddressBook::lookup(string strKey, string &strResult)
{
bool bSuccess = false; // seed result with failure
// create a pointer to the beginning of the map
// perform lookup.
// if found, set the result code
// set the results
// return
return bSuccess;
}
And finally add the code to finish the lookup.
bool CMyAddressBook::lookup(string strKey, string &strResult)
{
bool bSuccess = false; // seed result with failure
// create a pointer to the beginning of the map
map<string, string>::iterator ptr = addresses.begin();
// perform lookup.
ptr = addresses.find(strKey);
// if found, set the result code
if( ptr != addresses.end())
{
bSuccess = true;
// set the results
strResult = (*ptr).second;
}
// return
return bSuccess;
}
And you are done. You have satisfied the requirements of the program, done no excess code and the heart of the lookup is well-commented. To recap:
1. Write code to tell the story of how you want the program/solution to act.
2. Write enough code to get it to compile,
3. Write enough code (based on #2) so the application runs as expected.
Peace...
This basic method of development has served me well for years...
Peace...