Vous êtes sur la page 1sur 30

Standards de développement

Standards de Développement

Table des matières

Contrôle Document 4

Introduction 4

Principes de base 5

Qualité du code 6

Commentaires 7
Commentaires génériques 7
Commentaires fonctionnels 8

Convention sur les noms 9


Des motivations 9
Nom de (sous-)routine 9
Nom de section 10
Nom de variable locale 11
Des variables 12
Utilisation de variables 12

Du standard de codage 14
Considération générale 14

Structures de contrôle 18
Considérations sur les structures de contrôle 18

Champs Locaux 19
Considérations sur les LOCAL.REF 19

Instructions & commandes 20


Instructions à éviter - contexte navigateur 20
Instructions à éviter - perte de contexte 20
Instructions à utiliser 20

Performances 22
Instruction/opérateur à privilégier 22
Structure de contrôle 22
Utilisation des APIs 23
Architecture/Design 23
Sélections 23

Développements 25
Gestion de fichiers 25
Services Multithread 27

APIs du CORE 28
Traitement de date 28

2/30
Standards de Développement

Validation 28
Taux de change 28

Traitement de fin de journée 29

Compilation sous TAFJ 30

End Of Document 30

3/30
Standards de Développement

1. Contrôle Document

2. Introduction
L’objectif de ce document est de servir de guide aux équipes de développements lors de la
mise en œuvre technique des spécifications reçues. Ceci afin d’avoir une approche
cohérente aux développements réalisés dans le monde « T24 ».

L’adoption de ces « règles» devrait assurer une meilleure lisibilité du code, une meilleure
compréhension de la logique implémenté et surtout d’éviter les erreurs.
Il est inspiré du document « T24 Programming Standards.pdf » rédigé par Temenos.

4/30
Standards de Développement

3. Principes de base
Cette section reprend les règles basiques à suivre pour tous les codes écrits en JBASIC(R)

1. Se référer au standard de Temenos (R10 Coding Standards)

2. Le code source doit contenir moins de 600 lignes. Lorsque cette limite est
dépassé, faire appel à des « sous-» routines pour limiter le nombre de lignes de
code.

3. Le nombre d’arguments d’une routine ne devrait pas excéder 5. S’il est


nécessaire de passer un nombre important d’arguments, utilisez un « dynamic
array ».

4. Une routine ne devrait pas être monolithique mais composée de sections


(utilisation de GOSUB).

5. Dans les sections, évitez les blocs monolithiques (60 lignes de code ou plus),
pour une meilleure lisibilité limiter la à 10-20 lignes.

6. Tenez compte de la note donnée par le compilateur. Il est conçu pour donner
une note suivant des critères prédéfinis. Une note négative indique que le code
suit le standard.

7. Il est recommandé d’utiliser ECLIPSE(R) (DESGIN STUDIO(R)) afin de profiter


du GUI et d’autres fonctionnalités fournies

5/30
Standards de Développement

4. Qualité du code
Pour juger de la qualité d’un code, la note donnée par le compilateur est une indication mais
le critère le plus important est la clarté du code. Cette clarté est obtenue lorsque la suite des
instructions et l’objectif du code sont rapidement et facilement compris.
Pour y parvenir, il faut
1. Augmenter la lisibilité du code
2. utiliser des noms significatifs (pour les variables, sections, routines,..)
3. suivre les conventions de nommage
4. commenter le code

6/30
Standards de Développement

5. Commentaires
Les commentaires font partie des fonctionnalités les plus importantes fournies par un
langage de programmation. Bien qu’ignorés par le compilateur, elles rendent le code plus
compréhensible.
Sous T24(R), ils sont répertoriés en
1. Commentaires génériques
2. Commentaires fonctionnels

Commentaires génériques

Il s’agit de donner des informations relatives au projet telle que:


1. Le nom de la société
2. Le nom du développeur
3. Des indications liées au code
a. Type de routine
b. Dépendance
c. Paramètres en entrée
d. Paramètres en sortie
4. Une description succincte du programme
5. Historique des modifications
Exemple:
SUBROUTINE XXXX(ENQ.DATA)
* Company Name : Bank Name
* Developed By : Sofgen Dev Team/Mostefa
*--------------------------------------------------------------------------------------------

* Subroutine Type : VERSION /ENQUIRY/MAINLINE/PHANTOM/COB


* Attached to : VERSION Name/ENQUIRY Name/BATCH Record ID
* Attached as : CONVERSION/BUILD.ROUTINE/FIELD.VAL.RTN
* In Parameter :
* ENQ.DATA - Array with query details
* Out Parameter :
* ENQ.DATA - Array of records selected

Commentez les corrections d’anomalies, dans la partie historique des modifications, en


donnant les références de l’anomalie et en décrivant succinctement erreurs et correctifs
apportés.
*-----------------------------------------------------------------------------
* Modification History :
*-----------------------------------------------------------------------------
* 20190504 – BZ190401-001
* Enquiry crashes when date used is null.
* Fixed by defaulting the date to accounting date

7/30
Standards de Développement

Commentaires fonctionnels

Lors de l’implémentation, le développeur, en commentant les fonctionnalités codées, clarifie


la mise en œuvre des spécifications reçues.
Il est recommandé de donner une brève description de la section avant d’écrire du code.
*** <region name= INITIALISE>
INITIALISE:
*** <desc>Ouverture des Tables et initialisation des variables </desc>

GOSUB OPEN.FILES ; *Ouvre le(s) Tables requises


GOSUB GET.DEFAULTED.SECTOR ; *reprend tous les identifiants de CUSTOMER.DEFAULT

RETURN
*** </region>

8/30
Standards de Développement

6. Convention sur les noms


Des motivations

L’objectif en donnant des consignes pour le choix de l’identifiant (d’une variable, d’une
fonction, d'une routine, etc.) est de limiter le risque d’erreur et d’augmenter la
compréhension du code.
Dans cette section, nous allons spécifier des règles pour
1. Améliorer la lisibilité du code et sa compréhension
2. Connaître la valeur contenue par une variable
3. Comprendre la logique sous-jacente à l’utilisation d’une variable, d’une routine

De la nomenclature
Le choix de nom de routines, variables, fonction, répertoire procure des bénéfices
substantiels
1. Le code est plus lisible pour les autres, ainsi que pour le développeur.
2. La maintenance est plus simple: relire le code après plusieurs mois, s’avère plus
aisé.
3. Le code est plus facile de documenter
Le maitre mot ici est la « clarté ».

Nom de (sous-)routine

1. Ne devrait pas excéder 35 caractères


2. Les caractères « $ » et « _ » sont à proscrire
3. Préfixé par XX pour les développements réalisés réutilisables
Préfixé par l’abréviation utilisée pour la banque (AL, BC, CNEP,…) pour les développements
réalisés spécifiques non réutilisables
4. Suivi de préfixe lié au type de routine
a. V.INP (version input), V.AUT (version authorise), …
b. E (enquiry)
c. B (batch/service)
5. et avec un suffixe
a. .b : pour les Subroutine, program, function
b. .component: pour les component
c. .tut: pour les unites de tests
6. Le nom doit être expressif
Examples:
1. XX.V.INPUT.ACCOUNT.DETAILS.b

9/30
Standards de Développement

2. AL.E.GET.CUSTOMER.LOCAL.RATING.b
3. AL.B.CUST.UPDATE.RATING.b

Nom de section

1. Devrait être court (pas excéder 35 caractères), simple


2. Doit être expressif (pas exclusivement numérique) – à sa lecture, le développeur doit
comprendre la fonctionnalité
100250:
REM > Start reporting

LAUNCH.REPORT:
REM > Start reporting

3. Ne doit pas être surchargé de commentaires


DEFINE.PARAMETERS: * SEE „I_RULES‟ FOR DESCRIPTIONS *
REM > CALL XX.FIELD.DEFINITIONS

DEFINE.PARAMETERS:
* SEE „I_RULES‟ FOR DESCRIPTIONS *
REM > CALL XX.FIELD.DEFINITIONS

4. Devrait commencer par une courte description lorsque le nom n’est pas suffisant
pour expliquer la fonctionnalité

FIND.CLOSEST.SECTOR:
*** <desc>Trouve le code secteur le plus proche parmi les codes repris dans
CUSTOMER.DEFAULT </desc>

5. Ne devrait pas excéder plus de 20 lignes de code


6. Ne devrait avoir qu’une seule fonctionnalité
7. Ne devrait pas contenir de lignes de code devenues obsolète, surtout lorsqu’un outil
de gestion de version est utilisé
8. Ne doit pas être un mot réservé de Jbasic
Eviter:
GOSUB OPEN

OPEN:
CALL OPF (FN.CUSTOMER, F.
CALL OPF (FN.ETMB.H.DELINQ.CUST, F. CUSTOMER)
ETMB.H.DELINQ.CUST)
RETURN

OPEN est un mot réservé


Préférer:
GOSUB OPEN.FILES

OPEN.FILES:
CALL OPF (FN.CUSTOMER, F.CUSTOMER)
CALL OPF (FN.ETMB.H.DELINQ.CUST, F.ETMB.H.DELINQ.CUST)
RETURN

10/30
Standards de Développement

Nom de variable locale


1. Devrait être court (pas excéder 35 caractères) et simple
2. Doit être expressif
3. Devrait être utilisé : supprimer les variables initialisées non utilisées
4. Utiliser les abréviations standards T24 notamment celle relative à la gestion des
fichiers
*** <region name= OPEN.FILES>
OPEN.FILES:
*** <desc>Ouvre le(s) Tables requises </desc>
FN.CUSTOMER.DEFAULT = 'F.CUSTOMER.DEFAULT'
F.CUSTOMER.DEFAULT = ''
CALL OPF(FN.CUSTOMER.DEFAULT,F.CUSTOMER.DEFAULT)
RETURN
*** </region>

5. Ne devrait pas être ambigu :


a. Eviter d’utiliser plusieurs variables pour contenir la même valeur
b. Eviter d’utiliser comme nom, celui d’une section ou d’une routine
CONV.LBP.CCY:
*************
* Converting the USD amount to LBP equivalent Y.CCY.FROM = 'USD'
Y.CCY.TO = 'LBP'
CONV.LBP.CCY = ''
CALL EB.CURR.CONV (Y.CCY.FROM, Y.AMT.FROM, Y.CCY.TO, CONV.LBP.CCY)

RETURN

6. Ne doit pas être un mot réservé de Jbasic

11/30
Standards de Développement

Des variables

L’utilisation de variables est inhérente au développement. Elles sont caractérisées par le


type de données (la place en mémoire qu’elles occuperont) et de leurs visibilités en dehors
de la routine.
Cette visibilité leur confère le statut de
4. Variable locale : n’ayant d’existence que dans le corps de la routine
5. Variable globale : existence en dehors de la routine (variable COMMON
dans le jargon t24)
L’une des spécificités de T24 est l’utilisation
6. Variable dynamique : contient une multitude de valeurs,
et une part importante de ces variables dynamique est constitué de
7. Variable d’enregistrement : contient un enregistrement (par exemple
client, compte, …)

Utilisation de variables

1. Limiter l’utilisation des variables locales en leur préférant quand cela est possible
l’utilisation de variable globale
8. Eviter de lire l’enregistrement COMPANY
o ID.COMPANY & R.COMPANY sont des variables globales
9. Eviter de lire l’enregistrement USER
o OPERATOR & R.USER sont des variables globales
10. Etc…
2. Initialiser les variables qui sont utilisées tout au long du programme dans une section
d’initialisation.
3. Initialiser les variables liées aux boucles (FOR, LOOP) que dans le contexte proche
de la boucle et éviter de les utiliser ailleurs pour limiter les ambiguïtés et améliorer la
lisibilité
4. Eviter de passer des variables globales en argument.
· Eviter d’utiliser la variable globale telle que ETEXT
Ex: CALL F.READ(FN.CUSTOMER,CUSTOMER.ID,R.CUSTOMER,F.CUSTOMER,ETEXT)
5. Limiter les variables locales en utilisant des variables locales dynamiques.
L’utilisation de variables dynamiques regroupant des variables locales « similaires »
diminue la complexité du programme.
6. S’assurer avant de créer une variable locale qu’une la définition identique n’est pas
reprise dans les variables globales (COMMON).
· Exemple : TODAY, ETEXT, OPERATOR sont reprise dans I_COMMON
7. Ne pas modifier le contenu des variables globales de T24 qui altère la fonctionnalité
de celle-ci. Cela peut affecter négativement le comportement général des routines
faisant appel à elle.

12/30
Standards de Développement

· Exemple : TODAY = “20190401” peut avoir des répercussions négatives


importantes
8. Les variables d’enregistrements ne doivent pas être utilisées pour des
calculs/traitements, mais être la source pour le traitement et ou le réceptacle du résultat.
Eviter :
R.ACCOUNT<AC.WORKING.BALANCE> = R.ACCOUNT<AC.WORKING.BALANCE>*COM.AMT

Préférer:

WORKING BALANCE R.ACCOUNT <AC.WORKING.BALANCE>


TOT.AMOUNT = WORKING BALANCE * COM.AMT
R.ACCOUNT<AC.WORKING.BALANCE> = TOT.AMOUNT

13/30
Standards de Développement

7. Du standard de codage
Il s’agit ici de donner des lignes directrices pour
· permettre l’écriture de code source suivant les règles existant dans le « monde T24 »
· d’utiliser de manière appropriée les concepts du langage Jbase et les fonctionnalités
de T24.

Considération générale
1. Toutes les routines doivent avoir les « INSERT » de I_COMMON & I_EQUATE
2. Toute routine devrait avoir une section principale avec le code détaillé.
· Sa lecture devrait donner une compréhension du traitement à réaliser.
· Elle ne devrait contenir que
i. les INSERT (de variables globales et
dictionnaires),
ii. des GOSUB pointant une section dont le
traitement se terminera par un RETURN
iii. et un RETURN pour marquer la fin de la section
principale.

$INSERT I_COMMON
$INSERT I_EQUATE
$INSERT I_F.CUSTOMER
GOSUB INITIALISE
GOSUB GET.CUSTOMER.DETAILS
GOSUB SET.CUSTOMER.DEFAULT
RETURN

INITIALISE:
/STATEMENTS
RETURN

GET.DEFAULTED.SECTOR:
/STATEMENTS
RETURN

GET.CUSTOMER.DETAILS:
/STATEMENTS
RETURN

Donne plus d’indications que le code source ci-dessous que l’on retrouve répliquée mainte
fois. Il est correct dans la forme mais pas toujours dans l’esprit.
GOSUB INITIALIZE
GOSUB OPEN.FILES
GOSUB PROCESS
RETURN

INITIALIZE:
/STATEMENTS
RETURN

OPEN.FILES:
/STATEMENTS

14/30
Standards de Développement

RETURN

PROCESS:
GOSUB CALCULATE
RETURN

CALCULATE:
/STATEMENTS
RETURN

3. Utilisez des conditions préliminaires pour déterminer l’enchainement des traitements


GOSUB CHECK.RESIDENCE
IF CUSTOMER.IS.NON.RESIDENT THEN
GOSUB CALCULATE.FEE.4.NON.RESIDENT
END ELSE
GOSUB CALCULATE.FEE.4.RESIDENT
END
RETURN

CHECK.RESIDENCE:
* Set CUSTOMER.IS.NON.RESIDENT to TRUE if non resident
* Set CUSTOMER.IS.NON.RESIDENT to FALSE if non resident
RETURN

4. Utilisez, autant que possible, un tableau dynamique lorsque le nombre d’argument


est important
Eviter:
CALL INT.RATE(CUSTOMER.ID, CATEGORY, MNEMONIC, CURRENCY, WORKING.BALANCE, ACCT.OFF)

Préférer:

ACCT.ARRAY=CUSTOMER.ID:FM:CATEGORY:FM:MNEMONIC:FM:CURRENCY:FM:WORKING.BALANCE:FM:ACCT.OFF
CALL INT.RATE(ACCT.ARRAY)

5. Utilisez le dernier canevas pour créer des tables locales. Ce cadre permet de limiter
le nombre de lignes de code et de profiter des interactions standards via l’utilisation de
sous-routines suffixé avec le nom de la fonctionnalité désirée.
· .FIELD.DEFINITION : définition des champs
· .CHECK.FIELDS : règle de gestion du champ
· .CROSSVAL : règle de validation pour assurer la cohérence de
l’enregistrement
· Etc…
6. Evitez de dupliquer du code (copier/coller) pour des traitements identiques ou
similaires, préférer la création d’une section ou d’une routine. Cela facilite grandement
la maintenance et les mises à jour
7. Evitez de coder en dure, préférez l’utilisation de paramètres.
8. Utilisez PROGRAM pour créer une routine à exécuter via le « shell », utilisez
l’instruction STOP pour marquer la fin de la routine.
9. Utilisez SUBROUTINE pour créer une routine à ne pas exécuter via le « shell »,
utilisez l’instruction RETURN pour marquer la fin de la routine.
10. Les routines doivent avoir un seul point de sortie. Il ne devrait pas y avoir de
terminaison « anormale » due à des instructions EXIT, ABORT. Les instructions EXIT,
ABORT et STOP sont à proscrire.

15/30
Standards de Développement

11. Livrez les routines destinées aux tests sans les lignes de codes commentées. Cela
permet d’améliorer la lisibilité du code.
***
* IF YERR.ZC EQ '' THEN
* CITY.NAME = R.ZIPCODE.DETAILS<BNK.CITY.NAME>
* IF CITY.NAME NE TOWN.COUNTRY AND COUNTRY.ID EQ LOCAL.CTRY THEN
* AF = EB.CUS.POST.CODE
* ETEXT = "EB.CUS.WRONG.ZIPCODE"
* CALL STORE.END.ERROR
* END
* END
*END

12. Utilisez les commentaires pour clarifier le code et évitez les redondances. Notez que
l’utilisation de noms significatifs permet d’en limiter l’utilisation.
* Conversion of foreign currency to local currency
OUTSTAND.AMT = O.DATA
LENGTH.VAL=LEN (OUTSTAND.AMT); *Calculating the length of OUTSTAND.AMT
YCCY.FROM = OUTSTAND.AMT [1, 3];*Currency
YCCY.TO = LCCY;*USD
YAMT.FROM = OUTSTAND.AMT [4,LENGTH.VAL] ;*Amount part

13. Accédez aux champs d’un enregistrement via les noms repris dans le dictionnaire de
données (I_F) et jamais en utilisant la position. Une mise à jour éventuelle de la table
peut affecter les positions.
14. L’insertion de I_EQUATE rend l’utilisation du @ devant FM, VM et SM inutile.
MSG.COUNT = DCOUNT(MSG.SWEEP,@VM)

MSG.COUNT = DCOUNT(MSG.SWEEP,VM)

15. Privilégiez l’utilisation d’OPF, pour l’ouverture d’une table T24, à celle d’OPEN.
16. N’utilisez pas l’’instruction TXT pour des traitements sur le navigateur. Cette
instruction n’a d’effet qu’en mode console.
17. Ne codez pas en dure les messages de dépassement (OVERRIDE), utilisez
l’application OVERRIDE pour définir le message. Cela permettra d’utiliser toute les
fonctionnalités d’OVERRIDE.
IF ACC.BRANCH NE FT.BRANCH THEN
TEXT = " Non-Contingent PL items are being excluded from PL.CLOSE.OUT"
CURR.NO = 1
CALL STORE.OVERRIDE(CURR.NO)
END

IF ACC.BRANCH NE FT.BRANCH THEN


TEXT = "RE-EXCLUDING.PL.TYPES"
CURR.NO = 1 ;* Any numerical value
CALL STORE.OVERRIDE(CURR.NO)
END

18. Utilisez l’API STORE.END.ERROR pour la gestion des erreurs. Le message d’erreur
ne doit pas être codé en dure mais via l’application EB.ERROR.
IF CONV.REMB.PPL EQ "" THEN
ETEXT = "La fréquence de remboursement obligatoire"
AF = BNK.DATE.ECH
CALL STORE.END.ERROR
END

IF LIQ.DATE LT TODAY THEN


ETEXT = 'EB-BNK.LIQ.DATE.OVERDUE'
AF = BNK.LIQ.DATE

16/30
Standards de Développement

CALL STORE.END.ERROR
END

19. Evitez de mettre sur une même ligne plusieurs instructions, préférez l’indentation.
Cela augmente la lisibilité et diminue la complexité du code.
IF CUST.RESIDENCE EQ BNK.CTRY THEN RATE = (1+NR.FEE)

IF CUST.RESIDENCE EQ BNK.CTRY THEN


RATE = (1+NR.FEE)
END

17/30
Standards de Développement

8. Structures de contrôle

Les principales structures de contrôle en JBase sont


1. Les boucles
o FOR … NEXT
o LOOP … WHILE…
o LOOP … UNTIL…
Suivant le traitement à réaliser par la boucle, on privilégiera FOR…NEXT lorsque le nombre
d’itération est fixe et LOOP …UNTIL ou LOOP…WHILE dans les autres cas.
2. Les alternatives
o IF … THEN…END
§ IF…THEN… END ELSE … END
o BEGIN CASE … CASE… END CASE

Considérations sur les structures de contrôle

1. Privilégiez l’utilisation de LOOP...REMOVE pour lire une liste à FOR…NEXT. La


première est plus efficace.
2. Evitez les « IF » imbriqués et les « CASE » avec de nombreux cas pour diminuer la
complexité du programme et en améliorer sa lisibilité.
3. Privilégiez la lisibilité à la concision: Les syntaxes avec les instructions « IF »… , «
THEN »…, « ELSE » peuvent-être confuses
IF CONDITION THEN LOCATE VALUE IN RECORD SETTING POS THEN (Statement)
END ELSE
(Statements)
END

IF CONDITION THEN
LOCATE VALUE IN RECORD SETTING POS THEN
(Statement)
END
END ELSE
(Statements)
END

18/30
Standards de Développement

9. Champs Locaux

T24 permet d’ajouter des champs additionnels aux tables fournies. Cette fonctionnalité,
obtenue grâce au champ LOCAL.REF, est particulièrement intéressante et est également
disponible pour les tables locales.

Considérations sur les LOCAL.REF

1. Do not use OPF for the files in which only local reference field values are updated
using GET.LOC.REF. ???

2. Prenez en considérations les performances et limitez le nombre de « LOCAL.REF »


d’une application – il devrait ne pas dépasser 20.
3. Utilisez le nom et la fonction GET.LOC.REF pour déterminer la position d’une
LOCAL.REF et pas la position codée en dure.
LOCAL.FIELD.VALUES = R.CUSTOMER<EB.CUS.LOCAL.REF>
CENTRAL.BANK.SCORE = LOCAL.FIELD.VALUES<1,15>

APPL = "CUSTOMER"
LOCAL.FLD = "NAT.BANK.SCORE"
CALL GET.LOC.REF(APPL, LOCAL.FLD, POS.BANK.SCORE)
CENTRAL.BANK.SCORE = LOCAL.FIELD.VALUES<1,POS.BANK.SCORE>

4. Privilégiez l’appel à MULTI.GET.LOC.REF plutôt qu’à GET.LOC.REF lors de


l’utilisation de plusieurs LOCAL.REF liée à une même application.

CALL GET.LOC.REF("CUSTOMER", "CUST.ID", LR.CUST.ID)


CALL GET.LOC.REF("CUSTOMER", "MFO.CODE", LR.MFO.CODE)
CALL GET.LOC.REF("CUSTOMER", "NBU.B010", LR.NBU.B010)
CALL GET.LOC.REF("CUSTOMER", "USB.OBLAST", LR.USB.OBLAST)

APPL = "CUSTOMER"
LOCAL.FLDS = "CUST.ID":VM:"MFO.CODE":VM:"NBU.B010"
POS = ''
CALL MULTI.GET.LOC.REF(APPL, LOCAL.FLDS,POS)
CUST.ID.POS = POS<1,1>
NBU.B010.POS= POS<1,3>
MFO.CODE.POS= POS<1,2>

19/30
Standards de Développement

10. Instructions & commandes

Instructions à éviter - contexte navigateur

5. Evitez les instructions d’affichage CRT et PRINT dans les routines appelées via le
navigateur, elles n’ont pas effets
6. Evitez l’instruction INPUT dans les routines appelées via le navigateur, cela a pour
conséquence de bloquer le traitement en attendant une réponse qui ne viendra pas.
7. Enlevez les instructions DEBUG une fois les tests réalisés, un oubli bloque le
traitement.
8. Evitez la commande HUSH. Elle a pour but d'inhiber les sorties, notamment les
messages d’erreurs, et a pour effet de ne pas alimenter les fichiers COMO.
9. Evitez l’instruction INPUT.BUFFER, permettant reproduire la saisie clavier, pour le
passage de donnée ou naviguer dans le formulaire. Cette instruction n’est pas reconnue
dans le navigateur.

10. Do not use EQU command when array variables which do not have an underlying
table / file are EQUATED with numbers rather than names???

Instructions à éviter - perte de contexte

11. N’utilisez pas l’instruction CHAIN. Celle-ci transfère le contrôle d’une routine à une
autre sans revenir à la première
12. N’utilisez pas OFS.GLOBUS.MANAGER. Depuis la R09 son utilisation est fortement
déconseillée.
13. Notez que l’utilisation de CALLC n’est pas permise sous TAFJ.
14. Evitez de faire appel, sous TAFC, à des fonctions ou des routines ayant des
tableaux pour arguments.
15. Evitez absolument l’utilisation de STOP et ABORT. Enregistrez Les exceptions et
sortir normalement pour redonner le contrôle à la routine appelante.
16. Evitez l’instruction GOTO.

Instructions à utiliser

17. Utilisez la commande DEL pour supprimer des éléments dans un tableau dynamique
DEL NUMBER<5>

18. Utilisez l’instruction DEFFUN en préalable à l’utilisation d’une FUNCTION jbasic


19. Utilisez La fonction ABSS pour avoir la valeur absolue de chaque élément d’un
tableau dynamique.
20. Utilisez La fonction COUNTS pour avoir le nombre d’occurrence d’une chaine de
caractères dans chaque élément d’un tableau dynamique.

20/30
Standards de Développement

21. Utilisez la fonction ALPHA pour contrôler que tous les caractères d’une chaine sont
alphabétiques.
22. Utilisez la fonction TRIM pour supprimer des caractères dans une chaine. La
fonction permet de choisir le caractère à supprimer et la position (en début, en fin ou
dans toute la chaine) .
23. Utilisez les fonctions ICONV et OCONV pour la conversion de données, qu’il
s’agisse de date, temps ou de montants,
o ICONV permet de convertir en un format interne
o OCONV permet de convertir en un format externe
24. Utilisez l’opérateur AND dans les SELECT avec plusieurs conditions
SEL.CMD="SSELECT ":FN.CONTRACTS: "WITH BNK.FLAG EQ 'YES' WITH BNK.ID2 NE ''"

SEL.CMD="SSELECT ":FN.CONTRACTS
SEL.CMD:= " WITH BNK.FLAG EQ 'YES'"
SEL.CMD:= " AND BNK.ID2 NE ''"

21/30
Standards de Développement

11. Performances

Il est primordial de ne pas négliger l’aspect performance durant la programmation. Il arrive


souvent en fin de projet, lorsque cela n’a pas été pris en compte, qu’il faille revoir pour y
pallier. Cette section donne quelques pistes pour limiter le surcout lié au redesign.

Instruction/opérateur à privilégier
1. Privilégiez les opérateurs +=, -= , := ,…
TOTAL.FEES = TOTAL.FEES + ADDITIONAL.FEE

TOTAL.FEES += ADDITIONAL.FEE

2. Privilégiez l’opérateur := à <-1> pour constituer un tableau dynamique ayant un


nombre important de données. La différence est minime quand cela se passe au niveau
FIELD (FM) mais plus beaucoup plus importante pour les 2 autres niveaux (VM et SM)
3. Privilégiez la fonction CHANGE à la commande CONVERT. Temenos affirme que
dans certaine situation CHANGE est 20 fois plus rapide que CONVERT.
4. Privilégiez la fonction SUM pour réaliser une addition dans un tableau dynamique à
l’utilisation d’une boucle. Idem pour les fonctions COUNTS, ABSS, …

Structure de contrôle

5. Placez les conditions les plus utilisées en premiers dans un bloc BEGIN CASE …
END CASE.
6. Evitez de faire un traitement dans la zone de contrôle de boucle FOR…NEXT
FOR ACCOUNT.CNT = 1 TO DCOUNT(ACCOUNT.LIST,FM)-1
Statements
NEXT ACCOUNT.CNT

NUMBER.OF.ACCOUNT = DCOUNT(ACCOUNT.LIST,FM)-1
FOR ACCOUNT.CNT = 1 TO NUMBER.OF.ACCOUNT
Statements
NEXT ACCOUNT.CNT

7. Veillez à ne pas réaliser des traitements inutiles dans les boucles.


FOR CUSTOMER.CNT = 1 TO NUMBER.OF.CUSTOMER
SECTOR.ID = 1000
CALL F.READ(FN.CUSTOMER.DEFAULT,SECTOR.ID,R.CUSTOMER.DEFAULT,F.CUSTOMER.DEFAULT, CD.ERR)
Statements
NEXT CUSTOMER.CNT

SECTOR.ID = 1000
CALL F.READ(FN.CUSTOMER.DEFAULT, SECTOR.ID, R.CUSTOMER.DEFAULT, F.CUSTOMER.DEFAULT, CD.ERR)
FOR CUSTOMER.CNT = 1 TO NUMBER.OF.CUSTOMER
Statements
NEXT CUSTOMER.CNT

22/30
Standards de Développement

Utilisation des APIs

8. Evitez d’utiliser DBR. Cette routine lit l’enregistrement et récupère une seule valeur.
Temenos conseille de lire l’enregistrement dans son entièreté et d’utiliser les valeurs
désirées.
9. Utilisez autant que possible les APIs (routines et fonctions), elles sont optimisées.
10. Evitez de lier une routine à ACCOUNT.PARAMETER. Préférez l’utilisation de
VERSION/VERSION.CONTROL. La routine doit demeurer l’ultime recours
11. N’hésitez pas utilisez les API IN2 pour la valider la saisie de données. Elles
permettent de vérifier des montants, dates, numéro de compte, numéro de client, ….

Architecture/Design

12. Evitez les tableaux de dynamiques de grande taille (supérieur à 1024 bytes)
13. Calculez judicieusement le modulo à placer dans FILE.CONTROL
14. Prenez un soin particulier à la conception de CONCAT.
· Lorsque la taille de l’enregistrement est importante, il y une perte de
performance lors d’opération de lecture/l’écriture
· Changez le design si l’enregistrement d’un CONCAT contient plus de
1000 valeurs
15. Notez qu’au fur et à mesure de l’augmentation du nombre de valeurs et multi-valeurs
(VM & SM) d’un tableau dynamique, la performance se dégrade.
16. Utilisez le cache pour lire les données qui resteront statiques lors de l’exécution de la
routine. Le processus du cache, les ajoutera aux restes des données.

Sélections

17. Evitez les SELECT sur les tables ayant un nombre particulièrement importants
d’enregistrements. Privilégiez un CONCAT, une APIs ou toute alternative pour accéder
aux enregistrements recherchés. Les tables ci-après sont connues pour être
volumineuses :
· STMT.ENTRY , CATEG.ENTRY, RE.CONSOL.SPEC.ENTRY
· LIMIT.TXNS
· SC.POS. ASSET

18. Evitez d’utiliser SELECT lorsqu’un accès directe est possible (clé de l’enregistrement
connu).

19. Do not use condition selection in query file like CUSTOMER, ACCOUNT,
STMT.ENTRY, etc… chiefly in oracle database. This is because the condition query on
huge files may take up more time to extract values from the files. Instead use SELECT
condition and validate the condition criteria using LOOPS. ???

23/30
Standards de Développement

20. N’Utilisez pas de SELECT dans


· les routines appelées par VERSION, VERSION.CONTROL
i. INPUT routine
ii. VALIDATION routine
iii. AUTHORIZATION routine
iv. RECORD routine
· Dans la partie PROCESS d’un service

21. Un SELECT qui offre la possibilité de sélectionner plusieurs enregistrements et


envisagez d’utiliser la clause EQ plutôt que LIKE.

SELECT FBNK.ACCOUNT WITH CATEGORY EQ 1001 6001 5001

24/30
Standards de Développement

12. Développements

Gestion de fichiers

Dans cette section, nous allons traiter d’accès aux tables via des APIS telles que F.READ,
F.WRITE. Ces APIs sont des versions améliorées des commandes de base (READ,
WRITE,.. )

1. Initialisez tous les arguments de APIs et évitez de passer ‘’ comme argument


CALL F.READ (FN.ACCOUNT, ACCOUNT.ID, R.ACCOUNT, F.ACCOUNT, "")

ACCOUNT.ERR = ""
CALL F.READ (FN.ACCOUNT, ACCOUNT.ID, R.ACCOUNT, F.ACCOUNT, ACCOUNT.ERR)

2. Utilisez les verrous lors de la mise à jour. Utilisez F.READU pour verrouiller suivi de
F.WRITE pour déverrouiller avec mise à jour ou de F.RELEASE pour déverrouiller.

CALL F.READ(FN.CUSTOMER, CUSTOMER.ID, R.CUSTOMER, F.CUSTOMER, CUSTOMER.ERR)


GOSUB UPDATE.CUSTOMER
CALL F.WRITE(FN.CUSTOMER, CUSTOMER.ID, R.CUSTOMER)

CUSTOMER.RETRY = ""
CALL F.READU(FN.CUSTOMER, CUSTOMER.ID, R.CUSTOMER, F.CUSTOMER, CUSTOMER.ERR,CUSTOMER.RETRY)
GOSUB UPDATE.CUSTOMER
CALL F.WRITE(FN.CUSTOMER, CUSTOMER.ID, R.CUSTOMER)

3. Privilégiez CACHE.READ à F.READ pour la lecture de paramètres. La lecture à


partir du cache est plus rapide.

CALL CACHE.READ(FN.PARAMETER, PARAM.ID, R.PARAM,PARAM.ERR)

4. Inutile d’utiliser F.READ ou CACHE.READ lorsque l’enregistrement est une variable


globale (SPF, COMPANY, USER,…)

5. Utilisez F.DELETE pour supprimer un enregistrement d’une table et EB.CLEAR.FILE


pour la vider complètement ou partiellement.

6. Préférez l’utilisation de F.MATREAD à F.READ pour la lecture de tableau


dimensionné
MAT R.ENQUIRY.REPORT = ""
SIZE = 100
YERR = ''
CALL F.MATREAD(FN.ENQUIRY.REPORT,ENQUIRY.ID,MAT R.NEW, SIZE, F.ENQUIRY.REPORT, YERR)

25/30
Standards de Développement

7. Utilisez F.WRITE lors de la mise à jour d’un enregistrement. Contrairement à WRITE,


F.WRITE va écrire dans le cache en premier puis dans la base de données lorsque la
transaction est terminée ou lorsque le cache est plein.

8. Ne faites pas appel à JOURNAL.UPDATE dans une VERSION ou dans les routines
BATCH. F.WRITE se charge de le faire en tenant compte du cache.

9. Utilisez l’API F.LIVE.MATWRITE pour mettre à jour la piste d’audit d’un


enregistrement et d’alimenter le fichier $HIS

10. L’API TRANSACTION.ABORT permet d’annuler la transaction courante. Cela a


aussi pour effet de supprimer les écritures différées et de supprimer les verrous.

11. Portez une attention particulière lors de validation réalisée à partir de VERSION
lorsqu’il s’agit de mettre à jour une CONCAT ou que cela implique des écritures
comptables. Veillez à ajouter le code pour les fonctions de suppression et d’extourne.

BEGIN CASE
CASE V$FUNCTION EQ 'D'
GOSUB CHECK.DELETE ;* Special Deletion checks

CASE V$FUNCTION EQ 'R'


GOSUB CHECK.REVERSAL ;* Special Reversal checks

CASE OTHERWISE
GOSUB CROSS.VALIDATION
END CASE
*************************************************************************

CHECK.DELETE:
*If the V$FUNCTION EQ 'D' then the CHARGE Entries need to be deleted
*by calling #EB.ACCOUNTING

IF R.NEW(PDC.CHQ.PROCESS) = "PDC" THEN


CALL EB.ACCOUNTING('PODCTR','DEL','',0)
RETURN
END

IF R.NEW(PDC.CHQ.PROCESS) = "CLEARING" THEN


CALL EB.ACCOUNTING('CLR','DEL','',0)
END
RETURN

CHECK.REVERSAL:

IF NOT(V$FUNCTION = 'R' OR R.NEW(PDC.RECORD.STATUS) = 'REVE') THEN


RETURN
END

IF R.NEW(PDC.CHQ.PROCESS) = "PDC" THEN


CALL EB.ACCOUNTING('PODCTR','REV','','')
RETURN
END

IF R.NEW(PDC.CHQ.PROCESS) = "CLEARING" THEN


CALL EB.ACCOUNTING("CLR","REV","",0)
END
RETURN

26/30
Standards de Développement

12. Lors de l’utilisation de l’API EB.ACCOUNTING, portez une attention particulière aux
arguments.

Services Multithread

T24 permet de réaliser des traitements en parallèles en utilisant le multithread.


De manière générale, Le processus est scindé en 3 phases, dans l’ordre :
A. Initialisation :
o ouverture de fichiers, variables
o réalisée par chaque thread
B. Sélection :
o création de la liste à traiter
o réalisée un seul thread
C. processus :
o traitement sur un élément
o réalisée par chaque thread
Pour ce type de traitements il faut avoir à l’esprit que:
1. La LOAD routine doit contenir tous les appels à OPF.
2. La SELECT routine doit contenir l’appel à l’API BATCH.BUILD.LIST
3. Il est possible de séquencer le traitement en utilisant la variable globale
CONTROL.LIST.
a. l’initialisation de le CONTROL.LIST se fait dans la SELECT routine
b. à chaque appel à la SELECT routine, il y a un changement de séquence
4. Une SELECT routine ne devrait contenir que le traitement sur la CONTROL.LIST et
la(les) sélection(s).
5. La PROCESS routine ne doit pas contenir d’appel à OPF

27/30
Standards de Développement

13. APIs du CORE

Traitement de date
1. CDD : retourne le nombre de jours entre 2 dates.
REMAIN.CAL.DAYS = "C"
START.DATE = TODAY
REGION = ""
CALL CDD(REGION,START.DATE, EXPIRY.DATE, REMAIN.CAL.DAYS) ;* REMAIN.CAL.DAYS = 115

2. CDT : retourne la date calculée en ajoutant le nombre de jours à une date spécifiée
PROCESS.DATE = "20140606"
DAY.COUNT = "-3W"
REGION = ""
CALL CDT(REGION, PROCESS.DATE, DAY.COUNT) ; * PROCESS.DATE = 20140603

3. JULDATE : convertit une date julienne en une date grégorienne et vice-versa

GREGORIAN.DATE = "20120927"
JULIAN.DATE = ""
CALL JULDATE(GREGORIAN.DATE,JULIAN.DATE) ;* JULIAN.DATE = 2012271

4. DIETER.DATE : convertit une date de la forme YYYYMMDD en un format interne


USER.DATE = ''
T24.DATE.TODAY = '16446'
CALL DIETER.DATE(USER.DATE,T24.DATE.TODAY,'') ;* USER.DATE = 20130109

Validation
1. DUP : permet de s’assurer qu’il n’y pas de doublons
2. FT .NULL .CHECK : permet de s’assurer qu’il n’y pas de valeurs manquantes ( ‘’)

Taux de change
1. CALC.ERATE.LOCAL : retourne le taux de change entre la devise local et une
devise étrangère.
2. CUSTRATE : retourne le taux de change entre deux devises étrangères en se
basant sur vente/achat
3. EXCHRATE : retourne le taux de change entre deux devises étrangères
4. FCY.CONVERT.CHECK : suivant les arguments utilisés, retourne
a. Le résultat de la conversion d’un montant en devise locale en devise
étrangère et vice-versa
b. Le taux de change entre le montant en devise locale et devise étrangère
c. La différence en monnaie locale ou la différence en devise étrangère
d. La différence de taux

28/30
Standards de Développement

14. Traitement de fin de journée


1. Alimentez BATCH.NEW.COMPANY, dans un environnement MULTI-COMPANY,
avec les batch applicables à chacune des COMPANY
2. Les services doivent être en MULTI-THREAD
3. Ne pas tester le statut SPF dans le COB
4. Do not call template programs from batch. Isolate the program you require into
subroutine and then call the subroutine and the template program ???
5. Pas d’INPUT dans le COB
6. Pas de CRT dans le COB, utilisez OCOMO pour suivre le déroulement
7. Pas de HUSH ou !HUSHIT
8. S’il faut terminer brutalement un processus batch, n’utilisez pas STOP mais l’API
FATAL.ERROR
9. Ajouter un message d’erreur lors de l’utilisation de FATAL.ERROR. Cette information
se retrouvera dans EB.EOD.ERROR

29/30
Standards de Développement

Compilation sous TAFJ


A compléter

End Of Document

30/30

Vous aimerez peut-être aussi