Лично я предпочитаю экстремальное программирование, главный принцип для меня это то, что
программа должна работать сразу, пусть и в ущерб функциональности.
Приведу пример:
Допустим требуется написать программу, которая считывает из входного файла текст на испанском, переводит его на русский и записывает в выходной файл. Сначала выделяем шаги разработки:
1. Считать текст из входного файла.
2. Выполнить перевод.
3. Записать результат в выходной файл.
На первом этапе экстремальной разработки будет реализовано:
1. Считать текст из входного файла.
2. Записать текст без изменений в выходной файл.
3. Тестирование реализованного функционала.
На этом первый цикл разработки завершен. Программа работает, хоть и результат ее далек от ожидаемого.
На втором цикле начинаем реализацию пункта
"Выполнить перевод". Для этого нужно:
1. Разбить текст на предложения.
2. Выполнить перевод каждого предложения.
3. Тестирование реализованного функционала.
Далее реализуем
"Выполнить перевод каждого предложения":
1. Преобразовать предложение на испанском языке во внутреннюю структуру испанского языка.
2. Произвести анализ по внутренней структуре.
3. Преобразовать во внутреннюю структуру русского языка.
4. Преобразовать внутреннюю структуру русского языка в предложение на русском языке.
5. Тестирование реализованного функционала.
И так далее. Таким образом применяется написание кода в глубину. К конце каждого цикла разработки программа работает и постепенно преобретает функционал.
Чем короче цикл, тем лучше.
Кроме того, придерживаюсь правила реализации от общего к частному: если в текущем контексте есть две альтернативы, одна из которых теоретически может произойти, но она крайне редка, то реализовать прежде всего нужно вероятную альтенативу, а на маловероятную поставить заглушку.
switch ( tiempo )
{
case TIEMPO_PRESENTE_DE_INDICATIVO:
// разбираем настоящее время
ProcessTiempoPresenteDeIndicativo();
break;
...
case TIEMPO_PRETERITO_PLUSCUAMPERFECTO_DE_INDICATIVO:
// встречается не так часто, пока не реализуем
FATAL_ERROR
break;
...
default:
// вообще не известно, что это за время
FATAL_ERROR
break;
}
В данном случае пока не реализовали обработку настоящего времени, не стоит задумываться над более сложными временами, котоорые встречаются реже.
И наконец главное - тестирование. Очень важно поддерживать качественную отладку. Проверок много не бывает. И не стоит бояться, что они могут захламить код - отладку можно спрятать например под дефайны (если есть препроцессор) или под мертвый код. Например:
void ProcessTiempoPresenteDeIndicativo()
{
#ifdef DEBUG
if ( tiempo != TIEMPO_PRESENTE_DE_INDICATIVO )
{
FATAL_ERROR
}
#endif
...
}
Такая простая проверка застрахует от неуместного употребления функции.
Итого:
1. Экстремальный стиль программирования, состоящий из коротких циклов разработки.
2. Реализация от общего к частному.
3. Глубокая отладка.
Конечно имеют место и другие подходы к разработке программ..