O.O. Et si on codait comme en JAVA
mar 19 août 2025Introduction :
Dans le monde du développement sur IBM i, le RPG (Report Program Generator) reste un langage essentiel. Cependant, avec l’évolution des pratiques de programmation, il est possible d’intégrer des concepts modernes, similaires à ceux utilisés en Java, pour améliorer la qualité et la maintenabilité du code RPG.
1. Modularité et Procédures :
En Java, la modularité est assurée par la définition de classes, qui regroupent des propriétés et des méthodes.
En RPG ILE, il n’existe pas directement de notion de classe, mais tu peux t’en approcher en utilisant :
des modules qui jouent alors le rôle de « classes » en regroupant le nom de la classe, ses propriétés et ses méthodes.
De cette façon, tu obtiens une structure organisée et réutilisable, similaire à la modularité offerte par Java.
des copies/includes pour centraliser les propriétés et les prototypes de procédures,
Exemple :
Définition des classes
**FREE Dcl-DS LineOutput Qualified Template; chaine Char(132); END-DS;
- ligne 3 à 4 la classe LineOutput est définie,
- ligne 4, son unique propriété chaine est défini,
- Pas de constructeur ou de méthode pour cette classe(pour l’instant :-)).
**FREE
/include 'LineOutPut.rpgleinc'
// Spool class
Dcl-ds Spool Qualified template;
overFlow ind;
spoolName char(10);
Dcl-DS lineSpool likeds(lineOutput);
END-DS;
End-ds;
Dcl-PR setupSpool;
spoolAInitialiser likeds(Spool);
End-PR;
Dcl-PR OpenSpool EXTPROC('OPENSPOOL');
End-PR;
Dcl-PR WriteSpool EXTPROC('WRITESPOOL');
spoolAEcrire likeds(Spool);
End-PR;
Dcl-PR CloseSpool EXTPROC('CLOSESPOOL');
End-PR;- ligne 5 à 10 la classe Spool est définie,
- ligne 6 et 9, ses propriétés overFlow, spoolName, de simples variables, sont définis,
- ligne 8 et 9, cette propriété fait référence à une autre classe appelée LineOutput,
- ligne 12 à 14, est la déclaration d’un constructeur,
- ligne 16 à 24 sont les déclarations des prototypes des méthodes de la classe Spool.
Source des méthodes :
**FREE
Ctl-Opt NoMain Option(*SrcStmt : *NoDebugIO) Bnddir('SERVICES');
Dcl-F QSYSPRT PRINTER(132) usropn oflind(overflow);
/include 'Spool.rpgleinc'
/include 'commands.rpgleinc'
// ============================================================
//Construction du Spool
// ============================================================
Dcl-proc setUpSpool export;
Dcl-pi *n likeds(Spool);
spoolName Char(10);
end-pi;
Dcl-s rc Char(1);
Dcl-ds spoolAInitialiser likeds(Spool) inz;
// 1) Initialiser l’instance locale
spoolAInitialiser.spoolName = %Trim(spoolName);
execCommand('OVRPRTF FILE(QSYSPRT) TOFILE(*FILE) +
SPLFNAME(''' + %trim(spoolAInitialiser.spoolName) + ''') OVRSCOPE(*JOB)');
return spoolAInitialiser;
End-Proc;
// ============================================================
// Ouvre le spool.
// ============================================================
Dcl-Proc openSpool export;
Dcl-PI *N;
spoolAOuvrir Likeds(Spool);
End-PI;
monitor;
open QSYSPRT;
print('Executing: setUpSpool('+ %trim(spoolAOuvrir.spoolName) + ')');
on-error;
// ignore errors ...
// ... but try to remove the override.
monitor;
execCommand('DLTOVR FILE(QSYSPRT) LVL(*JOB)');
on-error;
dsply '*** Failed to delete QSYSPRT override! ***' rc;
endmon;
endmon;
End-Proc;
// ============================================================
// Écrit un message dans le spool.
// ============================================================
Dcl-Proc writeSpool export;
Dcl-PI *N;
MESSAGE CHAR(132) CONST;
End-PI;
Dcl-DS lineOutput likeds(LineOutput) INZ;
END-DS;
lineOutput = %trim(MESSAGE);
write QSYSPRT lineOutput;
End-Proc;
// ============================================================
// Ferme le spool.
// ============================================================
Dcl-Proc closeSpool export;
Dcl-PI *N;
End-PI;
if (%open(QSYSPRT));
close QSYSPRT;
endif;
End-Proc;Dans ce source complet,
- il y a des includes qui contiennent la déclaration de la DS(Classe et propriétés) et les prototypes des méthodes,
- et suivent ensuite les méthodes de cette classe SpooL
Parallèle d’usage
Java (esprit)
Spool s = new Spool("TESTSPL"); // setup
s.open(); // open
s.write("Hello"); // write
s.close(); // close
// ou try-with-resources pour garantir le close
RPG ILE
spool = setUpSpool('TESTSPL'); // setup (DS TEMPLATE, override posé)
openSpool(); // open (I/O commence ici)
writeSpool('Hello'); // write
closeSpool(); // close + nettoyage override
Pourquoi c’est familier aux développeurs Java
- Classe définis par une DS template
- Propriétés de la Classe contenus dans la DS template
- Dans le reste du source du module sont codés les constructeurs et les méthodes par l’intermédiaire de sous-procédures.
Le tout est compilé et lié sous forme de programme de service et vous avez accès à la Classe Spool dont on peut se servir des méthodes.
Dans les procédures appelantes, il suffit de de mettre l’include qui décrit la Classe, de créer les « objets nécessaires » en utilisant le mot clef LIKEDS sur la DS classe.
Comparatif Java ↔ RPG ILE
| Concept Java | Équivalent RPG ILE | Exemple |
|---|---|---|
| Classe | Module RPG + DS TEMPLATE | Spool.rpgle |
| Attributs (fields) | DS TEMPLATE (propriétés) | Spool |
| Méthodes | Procédures exportées | setupSpool, openSpool, writeSpool, closeSpool |
| Constructeur | Procédure d’initialisation | Dcl-DS mySpool LikeDS(Spool)suivi de l’appel de setupSpool |
| Objet (instance) | DS basé sur le TEMPLATE (LIKEDS) | Dcl-DS mySpool LikeDS(Spool_t) |
