Lorsque l'on désire créer un programme répondant à un cahier des charges bien défini (condition préalable évidement nécessaire), il faut déterminer quelles données il va falloir traiter, et comment les traiter. La première étape est donc de choisir comment représenter en mémoire ces données, et si plusieurs possibilités sont envisageables, choisir la plus appropriée aux traitements qu'il faudra effectuer (c'est à dire celle pour laquelle les algorithmes seront le plus facile à mettre en oeuvre). Dans un gros programme (C.A.O. par exemple), on appelle modèle la structure choisie pour stocker les données en mémoire.
Une fois ce modèle défini, le programme doit être écrit de manière structurée, c'est à dire être décomposé en petites entités (sous programmes, fonctions en C), réalisant chacune une tâche bien définie, en ayant bien défini quelles sont les données nécessaires en entrée du sous programme, et quelles seront les données retournées en sortie du sous programme (arguments ou dans certains cas variables globales). La réalisation pratique de la tâche doit ne dépendre que de ses entrées et sorties, et n'accéder à aucune autre variable (par contre elle peut utiliser pour son propre compte autant de variables locales que nécessaire). Ceci permet d'éviter les effets de bord, qui rendent la recherche d'erreurs (débogage) presque impossible.
Le choix d'un modèle est capital : devoir le modifier une fois le programme bien avancé nécessite en général la réécriture complète du programme, alors que modifier certaines fonctionnalités du programme correspond à ajouter ou modifier des sous programmes sans modifier les autres. C'est un des intérêts de la programmation structurée. Par contre, pour pouvoir plus facilement modifier le modèle, il faut des structures de données hiérarchisées et évolutives (disponibles dans les langages orientés objets). Un autre avantage de la programmation structurée est la possibilité de créer dans un premier temps chaque sous programme réalisant une tâche déterminée grâce à un algorithme simple, puis d'optimiser uniquement les sous-programmes souvent utilisés, ou demandant trop de temps de calcul, ou nécessitant trop de mémoire.
Parlons encore de l'optimisation d'un programme. On n'optimise un programme (ou du moins certaines parties) que si l'on estime que son fonctionnement n'est pas acceptable (en temps ou en consommation de mémoire). On devra choisir un algorithme en fonction des conditions d'utilisation du programme (on ne trie pas de la même manière un fichier totalement mélangé et un fichier déjà trié , mais avec quelques valeurs non triées en fin de fichier). A partir d'un moment, on ne peut plus optimiser en temps et en mémoire. Il faut alors choisir. Par exemple, un résultat de calcul qui doit être réutilisé plus tard peut être mémorisé (gain de temps) ou on peut préférer refaire le calcul (gain de mémoire). Par exemple, il est rare de passer par une variable intermédiaire pour utiliser deux fois i+1.