Principes de conception, meilleures pratiques et modèles de conception pour C (ou programmation procédurale en général)? [fermé]

91

Existe-t-il des principes de conception connus, des meilleures pratiques et des modèles de conception que l'on peut suivre lors de la conception d'un projet C? Ou des principes de conception utiles pour la programmation procédurale (impérative) en général?

(Je suis enfant de la 'génération orientée objet' et je dois concevoir un grand projet C pour la première fois)

Dimi
la source
1
Vous pourriez être intéressé par des réponses à cette question: stackoverflow.com/questions/661307/…
mouviciel
7
J'ai fait des recherches sur Internet et dans la bibliothèque universitaire, avant de poster ma question, et je n'étais certainement pas submergé par des livres sur la conception de logiciels pour C. noms, mais à propos d'une abstraction plus élevée, au niveau de l'architecture logicielle). En outre, je ne suis pas d'accord avec votre reproche de «dépendre des autres». Vous voulez dire que chaque programmeur doit se renseigner par lui-même sur les meilleures pratiques et les bons modèles de conception? C'est à coup sûr une question sur laquelle l'expérience des autres doit être utilisée.
Dimi
2
Désolé, Dimi, ce n'était pas à propos de vous en particulier, et je n'ai pas été très clair. Ce truc était transmis autant par la tradition orale que par tout autre moyen: il n'y avait pas un ensemble nominal de "Patterns" officiels, la réponse de Jonathon était ce que vous trouverez dans les livres, mais tout le monde savait que l'information se cachait. Il semble que la tradition orale se perd et de nombreux jeunes programmeurs pensent que la POO a inventé l'encapsulation et la séparation. Cette communauté semble avoir moins de sens de sa propre histoire que ce que j'aimerais voir. Ainsi ma reconnaissance que je suis dans un territoire grincheux de vieillard.
dmckee --- ex-moderator chaton
1
Je ne peux pas partager votre point de vue rétrospectif car il suffit de trouver mes marques sur le terrain, mais j'accepte votre suggestion. Merci de vous exprimer plus clairement, toujours d'une grande valeur pour arriver à lire le point de vue d'une personne expérimentée. J'apprécie vraiment votre contribution.
Dimi
La norme de codage SEI CERT C fournit un bon ensemble de règles et de bonnes pratiques communes ainsi que des choses que vous devriez essayer d'éviter d'utiliser.
Rami

Réponses:

65

Cachette d'informations - comme le soutient Parnas ( Software Fundamentals ).

Gestion soignée des en-têtes et de la visibilité:

  • Tout ce qui se trouve dans un fichier source qui peut être caché du monde extérieur devrait l'être; seule l'interface externe documentée doit être exposée.
  • Tout ce qui est exposé est déclaré dans un en-tête.
  • Cet en-tête est utilisé là où la fonctionnalité est nécessaire (et là où elle est définie).
  • L'en-tête est autonome - lorsque vous en avez besoin, vous l'utilisez, et vous n'avez pas à vous soucier de `` quels autres en-têtes dois-je également inclure '' car l'en-tête garantit qu'il fonctionne en incluant tout ce dont il a besoin pour le faire travail.
  • L'en-tête est auto-protégé - donc peu importe s'il est inclus plusieurs fois.

    #ifndef HEADER_H_INCLUDED
    #define HEADER_H_INCLUDED
    ...rest of header contents, including other #include lines if necessary
    #endif /* HEADER_H_INCLUDED */
  • Concevez des ensembles de fonctions pour travailler sur des «objets» (généralement des structures) - et utilisez ces fonctions plutôt que de fouiller dans les entrailles de la structure dans le code qui l'utilise. Pensez-y comme une encapsulation auto-imposée.

Jonathan Leffler
la source
Bon point, merci, Jonathan. Les types de données abstraits sont un autre bon exemple de dissimulation d'informations avec une séparation nette de l'utilisation et de la mise en œuvre (interface externe connue et implémentation interne inconnue).
Dimi
23

Mes trois conseils:

  • Écrivez des tests unitaires. Ils vous aideront à vous concentrer sur une conception qui répond à votre problème au fur et à mesure. Bien mieux que de s'appuyer (uniquement) sur une pensée pré-méditée.
  • Avoir un détecteur de fuite de mémoire (il existe toutes sortes de bibliothèques) installé et opérationnel dès le premier jour. Demandez à cette bibliothèque d'imprimer toutes les fuites dès que le programme / les tests se terminent. Cela vous permettra d'attraper une fuite dès que vous l'introduisez, rendant ainsi sa fixation beaucoup moins douloureuse.
  • Écrivez le code POO en C. Pas si difficile. Bien qu'il soit possible d'émuler le remplacement de méthode, je vous suggère de commencer par l'émulation d'objets simples. Même ce mécanisme simple peut vous offrir un kilométrage élevé.

Voici un exemple:

typedef struct Vector {
  int size;
  int limit;
  int* ints; 
} Vector;

Vector* Vector_new() {
  Vector* res = (Vector*) malloc(sizeof(Vector));
  res->limit = 10;
  res->size = 0;
  res->ints = (int*) malloc(sizeof(int) * res.limit);

  return res;
}


void Vector_destroy(Vector* v) {
  free(v->ints);
  free(v);
}

void Vector_add(Vector* v, int n) {
  if(v->size == v->limit) {
    v->limit = v->limit * 2 + 10;
    v->ints = realloc(v->ints, v->limit);     
  }

  v->ints[v->size] = n;
  ++v->size;
}

int Vector_get(Vector* v, int index) {
  if(index >= 0 && index < v->size)
    return v->ints[index];

  assert false;
}
Itay Maman
la source
Merci Itay. Je suivrai vos conseils.
Dimi
1
4. Ne lancez pas le résultat de malloc.
SS Anne le
22

Il existe un bon livre en ligne gratuit, intitulé Programmation orientée objet avec ANSI-C , qui couvre le sujet de l'écriture de code orienté objet en C. Une recherche Google sur «C orienté objet» donne également un certain nombre d'autres bons. exemples et ressources.

Si votre projet est critique pour la sécurité, MISRA-C est un bon ensemble de règles. Il est principalement destiné au c intégré, mais il peut également être utile dans d'autres domaines.

Je me considère comme un codeur OO et je travaille beaucoup avec le C intégré. Le meilleur conseil que je puisse donner, surtout pour les grands projets, est de ne pas en faire trop. Créer un framework OO complet au-dessus de ANSI C peut être très tentant, mais il faut beaucoup de temps et d'efforts pour bien faire les choses. Plus vous obtenez de fantaisie, plus vous passerez de temps à déboguer votre framework au lieu de travailler sur le vrai projet. Abordez la tâche avec une tête claire et une bonne et solide compréhension de YAGNI . Bonne chance!

e.James
la source
Merci, e.James. Je ne veux pas créer un cadre orienté objet au-dessus de ANSI C, mais rechercher des principes de conception de programmation procéduraux spéciaux et appropriés. L'astuce MISRA-C est très utile, notamment parce qu'il s'agit en fait d'un projet intégré. Je vais l'examiner de plus près.
Dimi
Ah, les joies de l'embarqué C. N'oubliez pas que vous devez déclarer vos variables en haut de votre fonction (ou en haut de n'importe quel { }bloc). Celui-là me mord toujours une ou deux fois:)
e.James
7

La POO est une méthodologie et non une technologie. Donc, mon premier conseil est d'arrêter de penser à cela comme de la programmation procédurale.

Au point de e.James, vous ne voulez pas essayer de recréer un langage orienté objet ou prétendre que vous en avez les capacités. Vous pouvez toujours faire toutes les bonnes choses en vous accrochant à quelques principes simples:

  1. Testez tout.
  2. Trouvez ce qui varie et encapsulez-le.
  3. Conception aux interfaces.

la source