LA CLOCHE

Il y a ceux qui ont lu cette nouvelle avant vous.
Abonnez-vous pour recevoir les derniers articles.
Email
Nom
Nom de famille
Comment voulez-vous lire The Bell
Pas de spam

Envoyez votre bon travail dans la base de connaissances est simple. Utilisez le formulaire ci-dessous

Les étudiants, les étudiants diplômés, les jeunes scientifiques utilisant la base de connaissances dans leurs études et leurs travaux vous seront très reconnaissants.

Posté sur http://www.allbest.ru/

MINIBRANAUKIRUSSIE

abstrait

"Programmation modulaire"

introduction

Au cœur d'un langage de programmation se trouve une certaine idée directrice provoquée par les besoins ou, plus souvent, par une crise dans le domaine de la programmation et du développement logiciel, qui a un impact significatif sur le style de programmation et permet de surmonter cette crise.

Programmation orientée machine est apparu simultanément avec la création d'ordinateurs électroniques. Au début, il s'agissait de programmes en codes machine, puis le langage de programmation Assembler (Autocode) est apparu, qui a un peu «humanisé» l'écriture d'un programme en code machine.

Programmation procédurale. L'idée principale de ce style est l'algorithmisation du processus de résolution du problème et le choix du meilleur algorithme (en termes de consommation de mémoire ou en termes de vitesse.

Programmation structurée. Ici l'idée principale est magnifiquement exprimée par N. Wirth dans son livre "Algorithms + Data Structures \u003d Programs". C'était une réponse à la crise de la programmation qui a commencé au milieu des années 1960, lorsque le code source dépassait les 1 000 lignes. En 1971, l'algorithmique langage Pascal et un peu plus tard, en 1972, le langage C.

Programmation modulaire. Ici, l'idée principale était de "cacher" les données et les procédures à l'intérieur d'unités de programme indépendantes - modules . Cette idée a été réalisée par N. Wirth en langage algorithmique Modula (1975-1979), puis "ramassé" et le reste des langages de programmation répandus à cette époque. Par exemple, des systèmes de programmation bien connus Turbo pascal et Turbo C.

Programmation orientée objet. Depuis le milieu des années 80, le volume de code source a franchi la barre des 100 000 lignes. Il était nécessaire de faire non pas une combinaison aléatoire de données et d'algorithmes pour leur traitement en un seul tout, mais un ensemble sémantique. Autrement dit, il était nécessaire de créer un nouveau niveau de programmation modulaire, lorsque l'accent est mis principalement sur la relation sémantique des structures de données et des algorithmes pour leur traitement

décomposition de la conception de la programmation du module

1. objectifprogrammation modulaire

Lors du développement de grands programmes, il est conseillé de collecter une partie des sous-programmes et d'autres ressources, telles que des variables, des constantes, des déclarations de type, et de les compiler séparément du programme principal sous la forme de bibliothèques de ressources ou de modules.

Lorsque vous commencez à développer chaque programme, il convient de garder à l'esprit que, en règle générale, il est grand systèmepar conséquent, des mesures doivent être prises pour le simplifier. Pour ce faire, un tel programme est développé en parties, appelées modules logiciels. Et cette méthode de développement logiciel elle-même est appelée programmation modulaire. Un module logiciel est tout fragment d'une description de processus qui est conçu comme un produit logiciel indépendant pouvant être utilisé dans les descriptions de processus. Cela signifie que chaque module de programme est programmé, compilé et débogué séparément des autres modules de programme, et donc physiquement séparé des autres modules de programme. De plus, chaque module logiciel développé peut être inclus dans différents programmes si les conditions d'utilisation, déclarées dans la documentation de ce module, sont réunies. Ainsi, un module logiciel peut être considéré à la fois comme un moyen de gérer la complexité des programmes et comme un moyen de gérer la duplication dans la programmation (c'est-à-dire comme un moyen d'accumuler et de réutiliser les connaissances du programmeur).

La programmation modulaire incarne les deux méthodes générales de gestion de la complexité dans le processus de programmation: garantir l'indépendance des composants du système et utiliser des structures hiérarchiques. Pour mettre en œuvre la première méthode, certaines exigences sont formulées qui doivent être satisfaites par un module logiciel, c'est-à-dire révèle les principales caractéristiques d'un «bon» module logiciel. Pour implémenter la deuxième méthode, des structures de programme modulaires en forme d'arbre (y compris des arbres avec des branches fusionnées) sont utilisées.

2. Le principalcaractéristiques du module logiciel

La taille un module est mesuré par le nombre d'instructions ou de lignes qu'il contient. Le module ne doit être ni trop petit ni trop grand. De petits modules conduisent à des structure modulaire programmes et peuvent ne pas couvrir les frais généraux associés à leur conception. Les modules volumineux sont peu pratiques à étudier et à modifier; ils peuvent augmenter considérablement le temps total des traductions de programmes répétées lors du débogage d'un programme. En règle générale, des modules logiciels d'une taille allant de plusieurs dizaines à plusieurs centaines d'opérateurs sont recommandés.

Force du module est une mesure de ses connexions internes. Plus la force d'un module est élevée, plus il peut cacher de connexions à la partie externe du programme et, par conséquent, plus il peut contribuer à simplifier le programme. Pour évaluer la force d'un module, Myers propose un ensemble de sept classes de modules classés par force. Le module a le degré de résistance le plus faible, durable par hasard... Il s'agit d'un module qui n'a pas de connexions significatives entre ses éléments. Un tel module peut être sélectionné, par exemple, lorsqu'une répétition de la même séquence d'instructions est trouvée à différents endroits du programme, qui est alors formé en un module séparé. La nécessité de modifier cette séquence dans l'un des contextes peut conduire à une modification de ce module, ce qui peut rendre erronée son utilisation dans d'autres contextes. L'utilisation de cette classe de modules logiciels n'est pas recommandée.

Fonctionnellement durable un module est un module qui exécute (implémente) une fonction spécifique. Lors de la mise en œuvre de cette fonction, un tel module peut utiliser d'autres modules. L'utilisation de cette classe de modules logiciels est recommandée.

Informationnellement durable un module est un module qui effectue (implémente) plusieurs opérations (fonctions) sur la même structure de données (objet d'information), qui est considérée comme inconnue en dehors de ce module. Pour chacune de ces opérations, un tel module dispose de sa propre entrée avec sa propre forme d'adressage. Une telle classe doit être considérée comme une classe de modules logiciels avec le plus haut degré de résistance. Un module d'information peut implémenter, par exemple, un type de données abstrait.

Module d'embrayage est une mesure de sa dépendance aux données d'autres modules. Il se caractérise par le mode de transmission des données. Plus l'adhérence d'un module à d'autres modules est faible, plus son indépendance par rapport aux autres modules est forte. Pour évaluer le degré d'adhésion, Myers propose un ensemble ordonné de six types d'adhérence de module. Le pire type de chaînage de modules est poignée de contenu... Il s'agit de la concaténation de deux modules, lorsque l'un d'eux a des références directes au contenu de l'autre module (par exemple, à une constante contenue dans un autre module). Un tel couplage de modules est inacceptable. Il n'est pas recommandé d'utiliser également poignée de zone commune - il s'agit d'un tel chaînage de modules lorsque plusieurs modules utilisent la même zone mémoire. Le seul type de couplage de module dont l'utilisation est recommandée technologie moderne la programmation est couplage paramétrique (Concaténation de données Myers) est un cas où des données sont transférées vers un module soit en y accédant en tant que valeurs de ses paramètres, soit à la suite de son appel à un autre module pour calculer une certaine fonction. Ce type de chaînage de modules est implémenté dans les langages de programmation lors de l'utilisation d'appels à des procédures (fonctions).

Routine module - c'est son indépendance par rapport à l'histoire des appels à lui. Le module s'appelle routine, si le résultat (effet) de son accès ne dépend que des valeurs de ses paramètres (et ne dépend pas de l'historique des appels). Le module s'appelle dépendant de l'histoiresi le résultat (effet) de son accès dépend de l'état interne de ce module, qui est modifié suite aux appels précédents. Myers ne recommande pas l'utilisation de modules dépendant de l'historique (imprévisibles), car ils provoquent l'apparition de bogues délicats (insaisissables) dans les programmes. Cependant, une telle recommandation n'est pas constructive, car dans de nombreux cas, c'est le module dépendant de l'historique qui est la meilleure implémentation du module à information stable. Par conséquent, la recommandation suivante (plus prudente) est plus acceptable:

o vous devez toujours utiliser un module de routine s'il ne conduit pas à un couplage de module médiocre (non recommandé);

o les modules dépendant de l'historique ne devraient être utilisés que lorsque cela est nécessaire pour fournir un couplage paramétrique;

o dans la spécification d'un module dépendant de l'historique, cette dépendance doit être clairement formulée de telle manière qu'il soit possible de prédire le comportement (effet de l'exécution) d'un module donné avec différents appels ultérieurs.

En relation avec cette dernière recommandation, il peut être utile de définir la représentation externe (orientée vers l'information de la personne) des états de l'historique dépendant du module. Dans ce cas, l'effet de l'exécution de chaque fonction (opération) mise en œuvre par ce module doit être décrit en termes de cette représentation externe, ce qui simplifiera grandement la prédiction du comportement de ce module.

3. Conceptionmodule

La conception modulaire fait référence au processus de décomposition de problèmes plus importants en sous-problèmes plus petits et plus faciles à gérer. La première étape de conception consiste à décider de la limite entre ces sous-problèmes.

Pour tirer le meilleur parti de la programmation modulaire, chaque sous-problème ou module doit avoir une entrée et une sortie. Dans ce cas, vous pouvez facilement surveiller le flux de contrôle dans le programme.

3. 1 Décomposition fonctionnelle

Lors de la résolution d'un problème au stade de la conception, le premier choix doit être la décomposition fonctionnelle, c'est-à-dire décomposer le problème en unités fonctionnelles plus petites et gérables, où chaque unité exécute une tâche terminée et facilement identifiable. Il existe de nombreuses façons de définir le contenu d'un problème. Voici quelques exemples d'unités similaires qui exécutent des fonctions spécifiques: obtenir la racine carrée d'un nombre; effectuer toutes les opérations par rapport au périphérique spécifié telles que les opérations d'E / S de disque, les opérations d'E / S de clavier; l'exécution d'un groupe d'actions commun à un moment spécifié, comme l'initialisation de zones de données; et des unités qui interagissent séquentiellement ou partagent des éléments de données communs, comme la lecture de données à partir d'un clavier et leur conversion en valeurs entières.

Dans la programmation de langage de haut niveau aujourd'hui, les décisions les plus courantes sont celles qui représentent la meilleure façon d'utiliser la segmentation des programmes. On constate souvent que certains modules sont liés en utilisant un ensemble de critères et d'autres modules sont liés en utilisant un autre. Chaque module doit comprendre des sections de programme facilement compréhensibles.

3.2 Minimiser le nombre de paramètres transmis

Parfois, vous trouvez qu'après avoir défini les modules du programme, vous avez créé quelque chose de lourd et de gênant. Cela se produit souvent lorsque les modules, pour exécuter les tâches qui leur sont assignées, ont besoin d'accéder à une grande quantité de données. Le plus souvent, cela peut facilement se produire si un module est affecté à plusieurs options. Pour connaître l'état du programme à un instant donné, un module doit accepter de nombreuses variables différentes. Si tel est le cas, et qu'il est révélé que le module accepte un grand nombre de paramètres, il est nécessaire de répondre aux deux groupes de questions suivants:

o Ce module tente-t-il plus d'une fonction? Le module nécessite-t-il des paramètres utilisés dans les sections non-module? Si les réponses à ces questions sont positives, alors il est nécessaire de revenir à une segmentation plus poussée de ce module.

o Le module est-il une vue fonctionnelle? L'appelant et l'appelé font-ils réellement partie de la même fonction? Si tel est le cas, rassemblez-les dans un module, même si le module résultant est trop grand. Ensuite, essayez à nouveau de segmenter le module de différentes manières.

La segmentation des modules via une vue fonctionnelle se produit souvent lorsqu'un programmeur découvre que deux sections de programme sont identiques ou très similaires l'une à l'autre. Le programmeur essaie alors de créer un module à partir d'eux. Il ne s'agit pas d'une programmation modulaire car le module résultant a une connexion non fonctionnelle.

Si, au cours du processus de conception, il s'avère que rien ne peut être fait pour éviter d'utiliser un grand nombre de références de données ou de passer des étiquettes de paramètres, vous devez revenir au début de la conception et vérifier l'exactitude du problème posé.

3.3 Minimiser le nombre d'appels nécessaires

L'un des avantages significatifs de la programmation modulaire est qu'un programme de base peut très souvent être conçu pour être lu comme une séquence de procédures appelées. Ce fait augmente considérablement la "compréhensibilité" du programme, puisque le lecteur peut se familiariser avec son flux principal et son fonctionnement après avoir lu seulement une ou deux pages du code du programme. Cependant, cette fonctionnalité peut également présenter des inconvénients. L'une des nombreuses statistiques de programmation les plus importantes indique que 90% du temps d'exécution des programmes typiques est consacré à 10% du code du programme. Cela implique que si ces 10% contiennent un grand nombre d'appels de procédures enchaînés, alors le temps total passé à gérer l'exécution du programme peut devenir un obstacle insurmontable à l'utilisation de cette approche.

Le temps supplémentaire passé à calculer une adresse valide dans le corps d'un module peut ralentir l'exécution d'un module spécifique par rapport à un programme spécifique étroitement codé.

Conclusion

Les grands programmes sont généralement développés et débogués en plusieurs parties. Dans ce cas, il est opportun que chacune de ces parties, appelée sous-programme, ait été conçue de manière à pouvoir être utilisée lors de la résolution d'une sous-tâche similaire dans le même programme ou même lors de la résolution d'autres problèmes. Borland Pascal implémente deux types de routines: les procédures et les fonctions.

Un module est une collection compilée autonome de ressources logicielles à utiliser par d'autres modules et programmes.

Toutes les ressources du module sont divisées en deux groupes: externes - destinées à être utilisées par d'autres unités logicielles, et internes - ressources de travail de ce module.

Technologie moderne pour le développement de produits logiciels, y compris l'exploitation systèmes Windows, est basé sur le concept de programmation orientée objet, qui maintient une approche unifiée des données et des programmes. Tout est basé sur le concept d'objet, qui combine à la fois les algorithmes et les données traitées par ces algorithmes. En conséquence, non seulement le développement des programmes est simplifié, mais également la technologie de l'utilisateur, qui a la possibilité d'utiliser des outils graphiques visuels et diverses invites lorsqu'il travaille en mode interactif (dialogue).

Publié sur Allbest.ru

Documents similaires

    Les principaux avantages de la programmation modulaire. Isolation d'une procédure: saisie d'un tableau depuis la console, affichage d'un tableau à l'écran, informations sur l'auteur et l'état du problème résolu avant et après traitement. Hiérarchie des procédures, caractéristiques de la finalité des modules.

    résumé ajouté le 29/01/2016

    Caractéristiques de la programmation modulaire: procédures et fonctions, modules et leur structure, tableaux et chaînes ouverts, paramètres non typés. Méthodes pour passer des paramètres aux sous-programmes dans Borland Pascal. Programmation orientée objet.

    test, ajouté le 28/04/2009

    L'essence de la programmation utilisant l'environnement Delphi 7 et ses capacités graphiques de base. La structure d'un module de programme compilé de manière autonome et ses principes. Techniques de base pour travailler avec des procédures graphiques, construire un arc, un cercle et une ellipse.

    term paper, ajouté le 16/12/2011

    L'émergence des premiers ordinateurs et l'émergence de la programmation «spontanée». Une approche structurelle de la décomposition de systèmes complexes. Développement de la programmation modulaire et orientée objet. Caractéristiques de l'approche par composants et des technologies CASE.

    présentation ajoutée le 14/10/2013

    L'histoire de la formation de la technologie de programmation traditionnelle. Objectifs et sujet programmation structuréecomme l'une des plus grandes avancées de la technologie de programmation. Sous-programme, types de structures de contrôle. Concept de programmation modulaire.

    présentation ajoutée le 11/05/2016

    Le sujet de la recherche porte sur les méthodes modernes de développement logiciel, telles que la programmation orientée objet et la conception visuelle, ainsi que la programmation structurée et modulaire. C ++ est un langage de programmation universel. Concepts clés.

    term paper, ajouté le 01/10/2009

    Pourquoi C ++. L'émergence et l'évolution du langage C ++. Comparaison des langages C ++ et C. Efficacité et structure. Programmation procédurale. Programmation modulaire. Abstraction de données. Programmation orientée objet. Amélioration de S.

    résumé, ajouté le 06/03/2004

    Aperçu des technologies et des systèmes systèmes d'information géographique... Conception systémique et fonctionnelle d'un module logiciel, son développement à l'aide d'environnements de programmation Visual C ++ 6.0, Qt 3.3.3. Etude de faisabilité de ce procédé.

    thèse, ajoutée le 13/03/2011

    Conception d'un module logiciel dans l'environnement de programmation Borland Delphi 7.0. Schémas d'algorithmes pour résoudre des problèmes sur les thèmes "Variables symboliques et chaînes", "Tableaux", "Travailler avec des fichiers", "Créer une animation". Implémentation d'un module programme, code programme.

    rapport de pratique, ajouté le 21/04/2012

    Conception système d'Information... Analyse des langages de programmation et solutions existantes pour l'administration du système de gestion de la base de données. Développement du module d'interaction et de la structure du programme. Modules d'autorisation et connexions à la base de données.

Dans n'importe quelle profession, pas seulement dans la programmation, vous ressentez différents états émotionnels au cours d'un projet:

  • Premièrement, il y a l'enthousiasme pour les perspectives et les opportunités.
  • Puis vient le frisson. Les premières erreurs et difficultés ne font que vous provoquer, forçant votre cerveau et votre imagination à travailler au maximum.
  • La concentration diminue alors. À un moment donné, vous cessez de prêter attention aux avertissements et aux erreurs mineures, reportant la résolution de ces problèmes à plus tard.
  • En conséquence, vous perdez la motivation. Vous corrigez une erreur - trois apparaissent. Vous essayez d'ajouter nouvelle fonction, mais vous jetez l'idée à la poubelle parce que vous ne voulez pas y passer beaucoup de temps.

Certaines personnes pensent que c'est normal: cela vaut la peine d'accepter et de vivre ce cycle à chaque fois. En fait, tout est un peu plus simple, et la solution ne réside pas dans le domaine de la psychologie, mais dans l'approche de création du code.

Le problème de programmation classique

Dans la littérature occidentale, il existe un terme «grosse boule de boue» pour décrire l'architecture d'un programme. Traduisons-le textuellement. Graphiquement, une "grosse boule de terre" peut être représentée sous la forme de points sur un cercle, symbolisant des éléments fonctionnels, et des lignes droites - connexions entre eux:

Cela ressemble à vos yeux avant de soumettre un projet, n'est-ce pas?

Ceci est une illustration de la difficulté avec laquelle vous devez travailler, du nombre de liens à considérer si une erreur se produit.

La programmation n'est pas une discipline unique: ici, vous pouvez et devez appliquer l'expérience d'autres domaines. Prenons un ordinateur, par exemple. Leurs fabricants ne pensent pas à la variété des tâches que l'utilisateur résout, et plus encore, ils n'allouent pas pour chaque petit processeur et mémoire. Un ordinateur est simplement une collection d'objets complexes indépendants qui sont combinés dans un seul boîtier à l'aide de connecteurs et de fils. Les objets ne sont pas uniques, pas optimisés spécifiquement pour vous, et néanmoins ils font leur travail avec brio.

En programmation, il existe exactement les mêmes solutions. Par exemple, les bibliothèques. Ils vous aident à éviter de perdre un temps précieux à réinventer la roue. Cependant, les bibliothèques ne sont pas efficaces pour des tâches particulières - la création prendra beaucoup de temps, et avec un taux de répétition unique, l'efficacité tend à zéro.

Dans ce cas, il est plus utile de se référer aux modules. Un module est un morceau de code logiquement complet qui a un objectif fonctionnel spécifique. Pour l'interaction des modules, des méthodes sont utilisées qui ne permettent pas de modifier les paramètres et les fonctionnalités. Les avantages de la programmation modulaire sont évidents:

  • Accélérez le développement.
  • Fiabilité accrue.
  • Simplification des tests.
  • Interchangeabilité.

La programmation modulaire est extrêmement efficace dans le développement de groupe, où chaque employé peut se concentrer uniquement sur son propre front de travail et ne pas revenir sur les décisions de ses collègues. Cependant, dans une approche individuelle, vous obtenez au moins les avantages décrits ci-dessus.

Mais ce n'est pas si simple.

Problèmes de programmation modulaire

L'idée même d'utiliser des modules ne simplifie pas grandement le code, il est important de minimiser le nombre de connexions directes entre eux. C'est là que nous arrivons au concept d'inversion de contrôle (IoC). Simplifié - il s'agit d'un principe de programmation dans lequel les composants individuels du code sont isolés au maximum les uns des autres. Autrement dit, les détails d'un module ne devraient pas affecter la mise en œuvre d'un autre. Ceci est réalisé via des interfaces ou d'autres vues qui ne fournissent pas un accès direct au code modulaire.

DANS vie courante Il existe de nombreux exemples. Vous n'avez pas besoin d'appeler le pilote pour acheter un billet d'avion ou vérifier l'heure de départ. Pour boire du lait, vous n'êtes pas obligé d'aller au village ou à l'usine et de vous tenir au-dessus de votre âme à la vache. Il y a toujours des intermédiaires pour cela.

Il existe trois principales implémentations dans la programmation modulaire:

  • Injection de dépendance. La manière dont chaque élément a sa propre interface, l'interaction des modules se fait par le biais d'interfaces.
  • Méthode d'usine. Il est basé sur l'existence d'un certain objet conçu pour créer d'autres objets. En d'autres termes, une introduction au programme d'un prototype qui réunit des caractéristiques communes à la plupart des objets. Il n'y a pas d'interaction directe entre les modules, tous les paramètres sont hérités de la "fabrique".
  • Méthode de service. Une interface commune est créée, qui est un tampon pour l'interaction avec les objets. Une fonction similaire dans la vie réelle est remplie par les centres d'appels, les magasins, les plateformes publicitaires, etc.

Bien que la première implémentation IoC soit la plus couramment utilisée, les deux autres sont meilleures pour les premières étapes de la programmation modulaire. La raison en est que la simple création d'interfaces ne limite que l'accès aux modules, et pour réduire la complexité du code, il faut également réduire le nombre de liens. Les interfaces qui font référence aléatoirement à d'autres interfaces ne font que compliquer le code.

Pour résoudre ce problème, vous devez développer une architecture de code. En règle générale, il est similaire à la structure de fichiers de toute application:

Ainsi, la prise en charge des principes de programmation modulaire, d'inversion de contrôle et d'une architecture d'application claire permettra de faire d'une pierre deux coups:

  1. Fournir une séparation claire du code fonctionnel. Lorsque des erreurs se produisent, vous pouvez identifier rapidement la source, et les correctifs n'entraîneront pas de nouvelles erreurs.
  2. Minimisez le nombre de liens. Cela simplifiera le développement en sous-traitant différents modules à plusieurs développeurs. Vous pouvez également concevoir chaque bloc indépendamment sans tenir compte des autres, ce qui permet également d'économiser du temps et des efforts.
  3. Créez une hiérarchie avec une ligne d'héritage claire. Cela augmente la fiabilité du code, car les tests sont plus faciles et les résultats sont plus informatifs.

Le respect du principe de modularité dans les grands projets permettra de gagner du temps et de ne pas renverser l'enthousiasme de départ. De plus, vous pourrez enfin vous concentrer sur le plus intéressant - la mise en œuvre des idées originales dans le code. Mais c'est exactement ce que chacun de nous recherche dans la programmation.

Le principe de base de la programmation modulaire est le principe de diviser pour conquérir. La programmation modulaire est l'organisation d'un programme sous la forme d'un ensemble de petits blocs indépendants, appelés modules, dont la structure et le comportement obéissent à certaines règles.

Notez qu'il faut distinguer l'utilisation du mot «module» quand on entend la construction syntaxique des langages de programmation (unité en Object Pascal), et quand on entend l'unité de découpage d'un gros programme en blocs séparés (qui peut être implémentée à la fois sous forme de procédures et en les fonctions).

L'utilisation de la programmation modulaire facilite le test de votre programme et la recherche d'erreurs. Les sous-tâches dépendant du matériel peuvent être strictement séparées des autres sous-tâches, ce qui améliore la portabilité des programmes créés.

Le processus d'augmentation de l'efficacité des programmes est simplifié, car les modules à temps critique peuvent être retravaillés plusieurs fois indépendamment des autres. De plus, les programmes modulaires sont beaucoup plus faciles à comprendre et les modules peuvent être utilisés comme blocs de construction dans d'autres programmes.

Le terme "module" en programmation a commencé à être utilisé en relation avec l'introduction de principes modulaires dans la création de programmes. Dans les années 70, un module était compris comme toute procédure ou fonction écrite selon certaines règles. Par exemple "Le module doit être simple, fermé (indépendant), observable (de 50 à 100 lignes), implémentant une seule fonction de la tâche, n'ayant qu'une seule entrée et un seul point de sortie." Cependant, il n'y avait pas d'exigences généralement acceptées et un module était très souvent appelé toute procédure jusqu'à 50 lignes.

Parnas a été le premier à formuler plus ou moins clairement les principales propriétés d'un module de programme: "Pour écrire un module, il devrait y avoir suffisamment de connaissances minimales sur le texte d'un autre." Donc! Parnas a été le premier à mettre en avant le concept d'information cachée dans la programmation.

Conformément à la définition de Parnasse, un module peut être toute procédure (fonction) distincte à la fois au niveau le plus bas de la hiérarchie (niveau de mise en œuvre) et haut niveau, sur lequel seuls les appels à d'autres procédures de module se produisent.

Cependant, seules des constructions syntaxiques telles que des procédures et des fonctions existant dans les langages des années 70 ne pouvaient pas fournir une dissimulation d'informations fiable, car elles sont influencées par des variables globales dont le comportement dans les programmes complexes est souvent difficile à prévoir. Ce problème ne peut être résolu qu'en développant une nouvelle syntaxe qui n'est pas influencée par les variables globales. Cette conception a été créée et nommée un module.

Pour la première fois, une structure syntaxique spécialisée d'un module a été proposée par N. Wirth en 1975 et incluse dans son nouveau langage Modula. La même année, une implémentation expérimentale du langage Modula a été réalisée. Après quelques révisions, ce nouveau langage a finalement été implémenté en 1977 et nommé Modula-2. Par la suite, des constructions similaires, avec quelques différences, ont été incluses dans d'autres langages de programmation: Pascal Plus (Welch et Bastard, 1979), Ada (1980), Turbo Pascal version 4.0 et d'autres.

Au départ, on supposait que dans la mise en œuvre de systèmes logiciels complexes, le module devrait être utilisé avec des procédures et des fonctions comme une structure qui unit et masque de manière fiable les détails de la mise en œuvre d'une certaine sous-tâche. Cependant, dans le langage Borland (Turbo) Pascal, toutes les capacités théoriques du module n'ont pas été implémentées. En particulier, ce langage manque de support pour les unités internes (similaire aux procédures et fonctions internes), l'import n'est pas assez flexible (clause uses), ce qui ne permet pas d'importer des objets d'autres unités de manière sélective. Cette circonstance, ainsi que le fait qu'avec l'apparence ordinateur personnel le cercle des programmeurs s'est considérablement élargi (et cela a considérablement réduit le niveau moyen de formation théorique des programmeurs), a conduit au fait que lors du développement d'applications sur ce, précédent Object Pascal, version du langage, les modules étaient principalement utilisés comme un moyen de créer des bibliothèques problématiques de procédures et de fonctions. Et seuls les programmeurs les plus qualifiés ont utilisé toute la puissance de cette construction de langage pour structurer leurs projets. Dans Object Pascal, les restrictions notées sur l'implémentation des modules demeurent, cependant, du fait que dans environnement Delphi chaque formulaire correspond nécessairement à son propre module et les actions algorithmiques non visuelles sont également, en règle générale, formalisées sous la forme de modules séparés, tous les programmeurs, quelles que soient leurs qualifications, ont commencé à utiliser la construction «module» pour son but initial.

Delphi a un support intégré pour le concept de programmation modulaire dans le langage Object Pascal, qui encourage un style de programmation progressif et robuste avec une utilisation intensive de modules, et distingue ainsi Delphi et Object Pascal des autres outils de développement d'applications modernes.

Ainsi, le nombre de modules du projet doit être déterminé par la décomposition de la tâche assignée en sous-tâches indépendantes. Dans le cas extrême, le module peut même être utilisé pour ne contenir qu'une seule procédure, s'il est nécessaire que l'action locale effectuée par celui-ci soit garantie comme étant indépendante de l'influence d'autres parties du programme pour toute modification du code du projet. En particulier, une telle utilisation du module est typique de la classe des problèmes en temps réel, dans laquelle le critère de fiabilité et de prévisibilité du comportement du programme est essentiel.

Considérons une autre question théorique liée à l'utilisation de la programmation modulaire. Cette question porte sur la forme d'un projet modulaire.

Donner une bonne forme à la structure hiérarchique d'un projet modulaire améliore le processus de son développement. Le nombre de modules qui connectent un module et le nombre de modules qui le connectent ont un impact sur la complexité du projet. Jordan (Yourdon) a nommé le nombre de modules branchés à partir d'un module donné, la portée ou la largeur du contrôle du module. De même que grande taille une largeur de contrôle très petite ou très grande est le signe d'une mauvaise modularité. En général, la largeur de la commande du module ne doit pas dépasser 10. Ce nombre est associé au nombre "magique" 7, qui se fonde sur les dispositions de la psychologie, en particulier, sur la théorie du "chunking" de l'information. La mémoire humaine à court terme a une capacité limitée à stocker des «éléments» d'information. Des expériences psychologiques ont montré que la capacité de notre mémoire à court terme se situe entre 5 et 11 «morceaux» (en moyenne - 7). Elle peut exploiter simultanément environ 7 «éléments» d'information. Lorsqu'une personne dépasse cette limite, elle est plus sujette aux erreurs. La réorganisation des informations décomposées en parties appropriées est une action importante pour utiliser efficacement la mémoire à court terme d'une personne et pour améliorer la compréhension du matériel. Les gens dans de nombreuses situations de la vie font une telle réorganisation inconsciemment. Cependant, le programmeur peut s'aider lui-même en refusant délibérément la largeur de contrôle du module, qui dépasse largement le nombre 7.

Comme pour la programmation dans l'environnement Delphi, les recommandations envisagées sur la forme d'un projet modulaire doivent être attribuées principalement aux modules créés par l'utilisateur, puisque Delphi génère automatiquement la majeure partie du code lié au traitement des formulaires, et le programmeur d'application n'a pas vraiment besoin de penser aux plug-ins standards.

En outre, les mêmes principes doivent être appliqués lors de la conception d'une hiérarchie de classes. Par exemple, dans la hiérarchie des classes Object Pascal prédéfinies, seules deux classes, TObject et Exception, ont des classes descendantes beaucoup plus immédiates que 7. Cela peut s'expliquer par le rôle de base global de TObject et la nature "énumérable" de la classe Exception. Pour trois autres classes, ce nombre est compris entre 8 et 9, et les autres classes ont moins de 7 descendants immédiats.

Pour réduire la complexité système logiciel il se décompose en de nombreux petits modules très indépendants. Un module est un programme fermé qui peut être appelé depuis n'importe quel autre module du système. C'est un morceau de code de programme qui est la pierre angulaire de la structure physique d'un système. En règle générale, un module se compose d'une partie interface et d'une partie implémentation. Les modules peuvent être développés sur différentes langues programmation et compilez séparément. Un haut degré d'indépendance des modules d'un système logiciel peut être atteint en utilisant deux méthodes d'optimisation: renforcer les connexions internes dans chaque module et affaiblir la relation entre elles. La programmation modulaire est apparue au début des années 60. XX siècle ... Lors de la création de systèmes logiciels, il offre les avantages suivants:

  • simplifie le développement et la mise en œuvre de systèmes logiciels;
  • il existe une possibilité de travail simultané (parallèle) des interprètes, ce qui permet de réduire le temps de création d'un système logiciel;
  • l'installation et la modification de PS sont simplifiées;
  • il existe de nombreux points de contrôle naturels pour suivre l'avancement du projet;
  • vous pouvez créer des bibliothèques des programmes les plus courants;
  • facilite la lecture et la compréhension du programme;
  • des tests plus complets sont fournis;
  • il devient plus facile de charger le rAM grand PS (l'efficacité de la distribution du programme entre les pages lorsque vous travaillez dans la mémoire virtuelle dépend de la façon dont il est divisé en modules).

Outre ces avantages, certains inconvénients peuvent entraîner une augmentation du coût d'un système logiciel:

  • le temps d'exécution du programme peut augmenter;
  • la taille de la mémoire requise peut augmenter;
  • les temps de compilation et de chargement peuvent augmenter;
  • les problèmes d'organisation de l'interaction intermodulaire peuvent être assez complexes.

Listons les principales propriétés et exigences des modules.

  • 1. Le module se pose en conséquence compilation séparée ou fait partie d'un résultat de compilation conjointe. Il peut activer système opérateur ou être un sous-programme appelé par un autre module.
  • 2. Le contenu du module peut être référer en utilisant son nom.
  • 3. Module devrait retourner le contrôle à celui qui l'a appelé.
  • 4. Le module peut adresse à d'autres modules.
  • 5. Le module doit avoir une entrée et une sortie. Parfois, un programme avec plusieurs entrées peut être plus court et occuper moins d'espace mémoire. Cependant, l'expérience de la programmation modulaire a montré que les développeurs préfèrent avoir plusieurs modules similaires, mais pas utiliser plusieurs entrées et sorties dans un module. Cela est dû au fait que l'unicité des entrées et sorties garantit un module fermé et simplifie la maintenance du système logiciel.
  • 6. Module relativement petite. La taille du module affecte le degré d'indépendance des éléments du programme, la facilité de lecture et de test. Il a été constaté que de petits modules permettent de construire des programmes plus faciles à modifier. Ces modules sont plus couramment utilisés, ils facilitent l'évaluation et la gestion du développement, et peuvent être recommandés aux programmeurs expérimentés et inexpérimentés. Les critères de résistance élevée et d'adhérence minimale pourraient être satisfaits en concevant le programme sous la forme de plusieurs grands modules, mais il est peu probable qu'un degré élevé d'indépendance soit atteint de cette manière. En règle générale, un module doit contenir de 10 à 100 opérateurs linguistiques de haut niveau (jusqu'à 200 dans certaines publications).

D'un autre côté, les petits modules prennent plus de temps à concevoir et fonctionnent plus lentement. Toutes sont constituées de plus de phrases sources, nécessitent plus de documentation et peuvent être moins agréables à écrire pour le programmeur.

  • 7. Le module ne doit pas conserver l'historique de ses appels pour contrôler son fonctionnement. Un tel module s'appelle prévisible. Un module qui garde des traces de ses états lors d'appels successifs n'est pas prévisible. Tous les modules PS doivent être prévisibles, c'est-à-dire ne doit stocker aucune information sur l'appel précédent. Des erreurs délicates, insaisissables et dépendant du temps se produisent dans les programmes qui tentent d'appeler plusieurs fois un module imprévisible.
  • 8. Structure de prise de décision dans un module doit être organisé de telle manière que les modules qui sont directement influencés par la décision prise sont subordonnés (appelables) par rapport au module prenant la décision. Ainsi, il est généralement possible d'exclure la transmission de paramètres d'indicateurs spéciaux représentant les décisions qui doivent être prises, ainsi que de prendre des décisions affectant le contrôle du programme à un niveau élevé dans la hiérarchie du programme.
  • 9. Minimiser l'accès aux données. La quantité de données à laquelle un module peut se référer doit être réduite au minimum. L'élimination de la concaténation par zone commune, données externes et format est un bon pas dans cette direction. Le concepteur devrait essayer d'isoler les informations sur une structure de données ou un enregistrement de base de données particulier dans un seul module (ou un petit sous-ensemble de modules) - peut-être en utilisant des modules robustes à l'information.
  • 10. Procédures internes. Une procédure interne, ou sous-programme, est un sous-programme fermé physiquement situé dans le module appelant. Ces procédures doivent être évitées pour plusieurs raisons. Les procédures internes sont difficiles à isoler pour les tests et ne peuvent pas être appelées à partir de modules autres que ceux qui les contiennent. Cela ne correspond pas à l'idée de réutilisation. Bien sûr, il existe une alternative: inclure des copies de la procédure interne dans tous les modules qui en ont besoin. Cependant, cela conduit souvent à des erreurs (les copies deviennent souvent "pas entièrement exactes") et complique la maintenance du programme car lorsque la procédure change, tous les modules doivent être recompilés.

Après qu'un intégrateur débutant clignote avec une LED, il décidera certainement d'écrire quelque chose de plus sérieux et, comme tout débutant, il n'aura qu'une seule envie «de faire tout fonctionner plus vite !!!». Dans une telle tentative de s'affirmer, il écrira tout dans un seul fichier, sans penser à la structure du programme, mais après un certain temps, lorsqu'une partie du plan sera mise en œuvre, il deviendra clair que plus le programme devient volumineux, plus il est difficile d'y trouver quelque chose. Cela le conduira à l'idée que le programme devrait avoir une structure et il ira sur Internet pour voir comment d'autres intégrateurs résolvent ce problème. Après avoir examiné à quoi ressemblent les programmes écrits par d'autres personnes, il a conclu que le programme était divisé en fichiers qui représentent des unités logiques complètes, cette partie de la fonction et les variables sont prises dans l'en-tête, et bien plus. Tout ce qui précède est mon expérience, mais tous les débutants vont de la même manière, donc je vais décrire ici ce que j'ai rencontré moi-même.

Supposons que nous ayons un programme qui affiche la température affichage LCD et quoi pour l'écran LCD, quoi pour le capteur de température ( ds18b20), une initialisation est nécessaire, ainsi que des fonctions pour les utiliser. Par conséquent, il serait logique de créer deux fichiers séparés lcd.c et ds18b20.c, qui contiendra les fonctions nécessaires au travail. Ces fichiers modules appelés, Je tiens à noter que chaque module est un indépendant, une unité logique qui peut être compilée séparément du reste du programme... Lors de la compilation d'un module, le compilateur en fera un fichier objet.

La prochaine question qui se pose, puisque le module est une structure indépendante, on peut dire " chose en soi», Alors elle n'a aucun lien avec le monde extérieur, et nous n'en sommes pas satisfaits. Pour connecter des modules au monde extérieur, utilisez fichiers d'en-tête, également appelés en-têtes / en-têtes et ils ont une extension .h... Vous pouvez nommer l'en-tête comme vous le souhaitez, mais il est plus pratique que son nom coïncide avec le nom du module, lcd.h et ds18b20.h, Je dois dire aussi que tous incluent des fichiers ( #comprendre) il est pratique de le placer dans l'en-tête et de le connecter uniquement au début du module.
Quand il n'y avait pas d'en-tête, le début de lcd.c ressemblait à ceci
#define F_CPU 8000000UL #include #comprendre
et après avoir créé l'en-tête, cela ressemblait à ceci
#comprendre

Mais alors une autre question se pose, que faut-il inclure dans l'en-tête?
Dans l'en-tête, vous devez placer les prototypes de fonctions qui peuvent être nécessaires dans d'autres modules de programme. Un prototype de fonction déclare uniquement une fonction et ne contient pas de corps de fonction, mais en le regardant, vous pouvez trouver le nom de la fonction, le numéro, le type d'arguments et le type de données de retour.
Dans le fichier lcd.h
void lcd_init (void); void lcd_write_symbol (symbole char); void lcd_write_string (char * str); void lcd_clear (void);
Dans le fichier ds18b20.h les prototypes suivants seront annoncés:
void ds18b20_init (void); uint8_t ds18b20_get_temperature (vide);

En ce qui concerne les macros, vous pouvez retirer les macros chargées d'effectuer la compilation conditionnelle
#define MAKE_CALIBRATION // décommenter pour l'étalonnage
Et quelque part dans le code, il y a une construction qui est exécutée si la ligne précédente n'est pas commentée
#ifdef MAKE_CALIBRATION touch_x - \u003d 300; touch_x \u003d 240 - touch_x / ((Xmax-Xmin) / 240); touch_y - \u003d 350; touch_y \u003d 320 - touch_y / ((Ymax-Ymin) / 320); #fin si
Vous pouvez également rendre les macros responsables de la sélection des broches auxquelles les périphériques seront connectés
#define D0 PORTA // donc les données sont transmises sur un bus 16 bits, #define D7 PORTD // pour cela nous utilisons deux ports

Mais en même temps, il n'est pas nécessaire de placer dans l'en-tête ce qui n'est pas nécessaire dans d'autres modules:

  • macros comme
    #define (LCD_PIN & 0X80) check_busy_flag
  • variables à n'utiliser qu'à l'intérieur du module avec mot-clé statique
  • variables avec qualificatif externe
  • prototypes de fonction nécessaires pour certaines actions intermédiaires, par exemple une fonction qui traduit un nombre en Format BCD

Maintenant, quelques mots sur la connexion des en-têtes lors de la programmation de microcontrôleurs AVR presque tous les modules incluent un en-tête pour fonctionner avec les ports d'E / S.
#include avr / io.h
Autrement dit, il se connecte à lcd.h et en ds18b20.h, maintenant si nous incluons ces deux en-têtes dans le fichier principal du programme, alors avr / io.h se connectera deux fois, même si un seul suffisait... Afin d'éviter une telle situation et que l'en-tête n'est pas connecté deux fois, utilisez #include gardesqui ressemble à ceci.
#ifndef _ENCODER_H_ #define _ENCODER_H_ // décorer comme un en-tête normal #endif
Cette construction permet au préprocesseur de déterminer que l'en-tête donné a déjà été inclus dans le programme et de ne pas l'inclure à nouveau. Vous pouvez en savoir plus à ce sujet.
Vous pouvez également limiter le nombre de connexions de fichiers à une en utilisant la construction
#pragma once // décorer comme un en-tête normal
Utilisation avantageuse #pragma une fois au lieu #include gardes peut être lu.
À propos, vous pouvez connecter non seulement des en-têtes, mais également des fichiers avec l'extension .desi nécessaire
#include "font.c"
Dans ce cas, un fichier de police est connecté pour afficher les lettres sur l'écran TFT.
C'est tout, je pense que c'est le minimum que tout programmeur de microcontrôleur novice doit savoir.

LA CLOCHE

Il y a ceux qui ont lu cette nouvelle avant vous.
Abonnez-vous pour recevoir les derniers articles.
Email
Nom
Nom de famille
Comment voulez-vous lire The Bell
Pas de spam