P R O G R A M M A T I O N S T R U C T U R E E =============================================== Qu'est ce que la programmation structurée? 1 une programmation sans ordre de débranchement. + pas de GOTO (en RPG le moins d'indicateurs possible) + des boucles et des blocs d'instructions utilisants au mieux les possibiblités des compilateurs actuels. 2 une programmation modulaire. + des modules INDEPENDANTS. + réalisant une fonction (et une seule ?). + le plus élémentaires possible. + possédant leur propre vision des variables (visibilité). 3 la séparation des condition des traitements. + séparer les traitements de leur condition d'exécution. |
1/ PROGRAMMER SANS ORDRE DE DEBRANCHEMENT. Eviter la programmation "spaghetti" Améliorer la lisiblité des programmes, donc leur maintenance. (performmances ?) 2/ mais, un large code imbriqué peut donner un résultat inverse de celui souhaité. (difficile de lire 15 DOxxx imbriqués) il est donc souhaitable d'accompagner les ordres structurés d'une PROGRAMMATION MODULAIRE. Un module = une fonction "logique". (une action à réaliser dans une situation donnée) un module est plus facile à tester, à maintenir, à faire évoluer. il est plus simple de lire un source modulaire, en ne s'attardant qu'aux modules qui nous concernent ou au contraire à leur condition d'exécution. |
en outre un certain nombre d'erreurs proviennent de l'utilisation abusive (modification intempestive) de variables communes. la notion de modules ou sous programmes permet (suivant le langage) de définir des variables privées (ou locales), seuls les paramètres étant partagés. C'est natif en PASCAL ou en C. (notion de fonctions) C'est possible uniquement par appel de pgm externes en RPG ou COBOL sur AS/400. AUJOURD'HUI cela ce fait au détriment des performances. ILE permettera de résoudre ce problème. avec les liens statiques: une compile produit un module (non exécutable) un exécutable peut être composé de plusieurs modules avec les *SRVPGM (programmes de service, équivalents des DLLs) un programme peut faire appel à une des fonctions d'un *SRVPGM. |
Les programmes externes (ou modules liables avec ILE) permettent une meilleure réutilisabilité du code. ==> Test, maintenance et évolution simplifiées. ==> Gain de temps à l'écriture de nouveaux programmes. 3/ Tout cela nous ammenne à adopter une philosophie de programmation qui consiste à séparer les traitements de leur conditions d'exécution. + en parfaite adéquation avec la méthode WARNIER (LCP) par exemple. + là encore, lisibilité et maintenance amméliorées. + approche à la programmation évènementielle, puis à la POO. Des produits comme VISUAL BASIC, ENVY/400, etc ... sont basés sur le concept de la programmation évènementielle. a/ vous définissez votre interface graphique. b/ vous associer à un élément de l'interface un évènement: (click de souris, entrée clavier, etc...) |
c/ avec visual basic vous écrivez une procédure (un sous programme) qui sera automatiquement exécuté si cet évènement survient. c'est donc le compilateur qui gére en partie les conditions. avec la POO, le problème est plus complexe puisque vous avez déja définit comment les objets devaient réagir en leur attribuant des METHODES. Ces METHODES ne sont jamais que des "formes" de sous programmes ASSOCIES à des données et charger de les manipuler. Mais les méthodes sont le SEUL moyen d'accéder aux données. (on dit que les données sont ENCAPSULEES.) Un OBJET pouvant être définit à partir d'un type d'objet existant (héritage) la réutilisabilté et la fiabilité sont plus grandes. et enfin des normes comme SOM et DSOM (bientot sur AS/400), permettent d'envisager l'achat d'objets prêts à l'utilisation. |
MISE EN OEUVRE SUR AS/400. 1/ utiliser une méthode de programmation. préparer un ordino avant d'écrire un programme. 2/ utilisation des codes structurés: - BANNIR : GOTO - CABxx - TAG - les indicateurs à gauche. (ILE RPG-IV n'en accepte plus qu'un) - DOxxx/ENDDO - IFxx/ELSE/ENDIF -ORXX - ANDXX - SELEC/WHxx/ENDSL - EXSR - CASxx/ENDCS - LEAVE - ITER |
3/ écrire modulaire exemple RPG: FMT C CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++ * boucle principale C WRITETITRE C EXFMTF1 image 1 C *IN03 DOWEQ*OFF C EXSR TRT1 C EXFMTF1 C ENDDO C MOVE *ON *INLR C RETRN * sous programme principal C TRT1 BEGSR C CODART CHAINARTCIF1 40 40 = NF C *IN40 IFEQ *OFF C EXSRTRT2 si OK C ENDIF C ENDSR |
FMT C CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++ * traitement d'un article existant C TRT2 BEGSR C SELEC suivant C TYPART CASEQ'1' TRT3 le type C TYPART CASEQ'2' TRT4 C CAS TRT5 = inconnu C ENDCS C EXFMTF2 affichage C ENDSR * etc , etc ... Pour limiter les problèmes de partage de variables chaque sous programme peut "déclarer" ses variables en entête. C TRTx BEGSR C* flag "déja passé par ce sous pgm. C* MOVE ' ' FLAG1 1 C* compteur du nombre de passages C* Z-ADD0 CPT1 30 ... |
Essayez les variables de navigation. FMT C CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++ C MOVE '1' NAVI 1 C NAVI DOUEQ'F' C NAVI CASEQ'1' SP1 C NAVI CASEQ'2' SP2 C NAVI CASEQ'3' SP3 C ... C ENDCS C ENDDO C MOVE *ON *INLR * image 1 C SP1 BEGSR C EXFMTF1 C *IN03 IFEQ *ON C MOVE'F' NAVI C ELSE C MOVE'2' NAVI C ENDSR |
FMT C CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++ * test de l'existance de l'article SP2 BEGSR CODART CHAINARTICF1 40 *IN40 IFEQ *ON MOVE '1' NAVI ELSE MOVE '3' NAVI * préparation de l'écran EXSR SPMEP ENDIF ENDSR |
FMT C CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++ * affichage de l'écran 2 (visualisation de l'article) * sur cet écran :l'utilisateur peut faire F3 ( = sortie) * l'utilisateur peut faire F12 ( = image 1) * le code article peut être modifié(60 = CHANGE dans le DSPF) * * si aucune action, on reste sur cette image. C SP3 BEGSR C EXFMTF2 C SELEC C *IN03 WHEQ *ON C MOVE 'F' NAVI C *IN60 WHEQ *ON C MOVE '2' NAVI C *IN12 WHEQ *ON C MOVE '1' NAVI C ENDSL C ENDSR |
Si vous faites des programmes indépendants : - pensez au partages de fichiers paramètre SHARE(*YES) - gardez les programmes appellés actifs en RPG ils se terminent par RETURN le pgm principal appel un CL: PGM RCLRSC LVL(*CALLER) ENDPGM qui désactive TOUS les pgms appellés ferme TOUS les fichiers ouverts par les pgms appellés. en CL cela est impossbile (RETURN et ENDPGM sont indentiques) il vaut mieux faire en sorte que le CL appel le pgm RPG. |