Es werden grundsätzlich englische, sprechende Namen verwendet. |
Englisch ist die Sprache in internationalen Projekten. Es werden keinerlei
Abkürzungen verwendet, die nicht allgemein
gebräuchlich sind (html ist verwendbar), auch nicht cpy für copy, pgm
für programm oder obj für object.
Kurznamen sind nur dort erlaubt, wo sie erzwungen sind, also für
Programme, Module und Dateinamen. |
Variablennamen werden in gemischter Groß/Kleinschreibung geschrieben und
bezeichnen Substantive oder Adjektive, bei zusammengesetzten Wörtern
beginnt jeder Wortbestandteil mit einem
Großbuchstaben. Von RPG verwendete Schlüsselwörter werden nicht
verwendet, Variablennamen fangen nicht mit
SQL an (wegen embedded SQL). Sonderzeichen wie # % § in Namen werden nicht
verwendet (Problem im internationalen
Umfeld). |
Lokale Variablen in Prozeduren werden mit kurzen Namen benannt, globale
Modulvariablen mit längeren Namen, Variablen
Exporte sollten nur in Ausnahmefällen verwendet werden und mit dem
Modulnamen als eindeutigem Präfix versehen werden
Importe von Variablen zur Bindezeit sind nicht erlaubt; gegebenen Falls ist zur
Laufzeit zu binden (über API QleGetExp). Globale Pseudo
Typdeklarationen, auf die mit Like Bezug genommen wird, müssen in
Qualified Datenstrukturen vorgenommen werden, die mit dem Namen
der Copystrecke als Präfix versehen werden. Bei der Verwendung maroder SQL
Precompiler sind Ausnahmen möglich (Vorsicht:
Präfix SQL ist bereits reserviert). |
Prozedurnamen werden in gemischter Kleinschreibung geschrieben und bezeichnen
Verben mit sprechenden Erweiterungen; exportierte
Prozeduren sollen, Exportnamen müssen mit dem Modulnamen als Präfix
versehen werden. |
Exportierte Symbole müssen eindeutig sein. Um Bindefehler
auszuschließen müssen Exportnamen
(Eintrag bei Schlüsselwort EXTPROC der Prototypen) mit Modulnamen als
Präfix versehen werden, die eindeutigen Exportnamen
sollen bevorzugt verwendet werden, weitere Pseudo qualifier als suffix oder
prefix sind zu vermeiden (Ein Zugrifsmodul heißt ARTICLEund die Prozedur
zum
lesen ARTICLEread() und nicht readArticle() oder ähnlich). |
Namen von Konstanten bezeichnen Substantive und werden in Großbuchstaben
geschrieben, zusammengesetzte Begriffe werden
mit _ verkettet. |
Globale Konstanten können als Export oder über Copy Strecken
abgebildet werden. Bei Copy Strecken sollte die Deklaration
über eine Datenstruktur und Präfix mit qualified eindeutig gemacht
werden. |
Alle Deklarationen erfolgen in D Bestimmungen. |
Deklarationen von exportierten Prototypen erfolgen grundsätzlich in
Copystrecken, die in einer eigenen Quelldatei QRPGLEH
geführt werden. Name von Modul, Quelle, Header und zugehörigen
Objekten (SRVPGM oder PGM) sind gleich. |
Die Programme werden einheitlich gegliedert. |
Für einheitlichen Grundaufbau empfiehlt sich der Einsatz eines Generators,
der aus den Prototypen der Exporte Programmrahmen
generiert (GENFRAME auf der Open Source Seite www.bender-dv.de). Trennlinien
innerhalb von Prozeduren und Deklarationsblöcken stören die
Lesbarkeit, zur Blockbildung reicht eine Leerzeile ohne Schmuck völlig aus. |
Schachtelungen und Strukturblöcke werden durch Einrückung deutlich
gemacht. |
Hieraus ergibt sich die bevorzugte Verwendung von "Free Format" (Ausnahme:
Deklarationen und embedded SQL). Die
Füllwörter EVAL und CALLP sind grundsätzlich wegzulassen, Bei
Aufrufen ohne Parameter ist ein leeres Klammerpaar
zu verwenden. |
Schichtentrennung hat oberste Priorität. |
Module und werden klar nach Schichten getrennt. Ein Modul, das einen Bildschirm
ausgibt, oder Druckausgaben macht,
liest keine Daten und Geschäftslogik wird in separaten Modulen
implementiert. Ein Serviceprogramm hat ein Modul,
Procedures gehören nur gemeinsam in ein Modul, wenn sie gemeinsame
Zustandsgrößen teilen (globale Variablen). |
Zur Modularisierung sind SubProcedures einzusetzen. |
Subroutines werden nicht verwendet. Jede Procedure umfasst maximal zwei
Bildschirmseiten, weniger ist mehr. Modularisierung
beginnt immer mit der Benamung, lässt sich kein treffender Name finden,
ist der innere Zusammenhalt eines Moduls
(hier procedure) schwach. |
Die main Procedure ruft nach Parameterprüfung sofort eine lokale Procedure
auf. |
Die Eingangsprozedur (unbenannte) ist ein technisch notwendiger Mechanismus,
mehr nicht; durch sofortige Verzweigung in
eine Subprocedure stehen dort lokale Variablen zur Verfügung. Die
Schnittstelle ist durch ein globales Procedure Interface zu
beschreiben, ENTRY PLIST wird nicht verwendet. |
Variablen Export wird nicht verwendet, lokale Deklarationen werden bevorzugt,
globale Deklarationen werden für Status behaftete
Zustandsgrößen benutzt. |
Ausnahme von dieser Regel sind Variablen, die von embedded SQL verwendet
werden, diese werden global deklariert und
einheitlich mit ES_ Prefix versehen und nur als Workfelder für embedded
SQL verwendet. In globalen Deklarationen werden
keinerlei Feldüberlagerungen verwendet, für Extrahierungen und
Konvertierungen sind immer entsprechende Subprocedures
mit sprechendem Namen zu verwenden. |
Parameter |
Parameterübergabe by Value wird bevorzugt, bei dynamischen Aufrufen ist
die übergabe als Konstante die Regel. Es wird klar
unterschieden zwischen Übergabe und Rückgabe. Bei Procedures erfolgt
die Rückgabe als Rückgabewert bei der return
Anweisung; Rückgabe mehrere Werte erfolgt in Datenstrukturen. Verdeckte
Informationsübergänge sind zu vermeiden; Procedures
arbeiten mit Zustandsgrößen, Informationsübergänge werden
durch Parameter abgebildet. |
Dokumentierung der Programmerstellungsbefehle in der Quelle. |
Programme müssen reproduzierbar gleich erstellt werden können. Ein
einfacher Weg besteht darin, die Befehle zur Erstellung von
Programmen und gleichartigen Objekten in der Quelle selber als Kommentar zu
dokumentieren. Es bietet sich an einen
Präprozessor zu verwenden, der die Befehle ausliest und die Objekte
automatisch erstellt (CRTCPP auf der Open Source Seite
www.bender-dv.de) |
Keine Binderverzeichnisse und keine Binder Language verwenden. |
Bindefehler können schwerwiegende Auswirkungen haben (Störung
Transaktionslogik), deswegen ist es vorzuziehen alle
Bindeangaben explizit vorzunehmen. Bei der änderung von Exporten ist
grundsätzlich alles neu zu binden, was betroffen
ist. Programmerstellung muss einfach und sicher sein. Bei großen
Anwendungen ist Change Management Software dem
Mut zum Risiko vorzuziehen. |
Keine Module by Copy binden |
Schwache Bindung und kleine Bindeeinheiten bevorzugen. Grundsätzlich nur
by reference binden und dazu aus Modulen
Serviceprogramme erzeugen. Idealerweise dynamisch zur Laufzeit binden, dazu ist
ein open Source Tool verfügbar (PROCP4NAMEauf der Open Source Seite www.bender-dv.de). |
Benamte Aktivierungsgruppen für Programme verwenden |
Für Programme grundsätzlich Name der Quelle mit dem Entry Modul, Name
des Moduls, Programmname und Name der
Aktivierungsgruppe gleich nennen. |
Serviceprogramme mit *CALLER oder eigener benamter Aktivierungsgruppe
erstellen. |
Eigene Aktivierungsgruppe (gleich Modulname) bei eigener Commitdefinition und
bei Modulen ohne Zustand sinnvoll. |
Deklarattionen ausschließlich in D Bestimmungen |
Alle Deklarationen in D Bestimmungen mit minimalem Scope. Namen mit Leerzeichen
trennen, bei Datenstrukturen einrücken
und Langnamen in extra Zeile nutzen. |
Konstanten statt Literale verwenden. |
Keine Literale im Programm verwenden, sondern stattdessen Konstanten
deklarieren. Bei numerischen Werten ist es oft
klarer Variablen mit Initialisierung zu verwenden, da für Konstanten nur
eingeschränkt Typ Eigenschaften deklariert werden
können. |
Feldüberlagerungen und doppelte Deklarationen vermeiden. |
Keine verdeckten Informationsübergänge, Overlay und andere
Überlagerungstechniken meiden, in globalen Deklarationen strikt
unterlassen. Informationsübergänge nach dem Prinzip gleicher Name
gleicher Inhalt zwischen Dateipuffern und Datenfeldern
durch eindeutige Präfixe oder qualified Datenstrukturen ausschließen. |
Boolean Variablen statt Bezugszahlen verwenden. |
Keine implizit deklarierten Bezugszahlen verwenden, statt dessen sprechend
benamte Boolean Variablen deklarieren und diese
über Konstanten TRUE und FALSE belegen und abfragen, statt *ON und *OFF
und 0 oder 1 zu verwenden. |
Rechenfelder selber deklarieren anstatt vom Compiler erstellte Zwischenfelder |
Vorsicht mit geschachtelten Rechneausdrücken, statt das Rundungsverhalten
durch Extender zu beeinflussen, lieber
Zwischenwerte in selbst deklarierte Felder mit vorgegebener Genauigkeit stellen
lassen, Literale und numerische Konstanten
beim rechnen lieber durch Variablen ersetzen, oder durch Zuweisung entsprechend
Casten. Keine Typumwandlungen durch
Feldüberlagerung vornehmen, stattdessen Built in Functions oder eigene
Procedures zum Casten verwenden. |
Rechenoperationen in Ausdrücken formuliern. |
überflüssige Operation Codes für numerische Berechnungen nicht
verwenden. Stattdessen Zuweisungen und Ausdrücke
codieren, für Zeitberechnungen entsprechende Built in Functions. |
Bit Frickeleien unterlassen. |
Biton und Bitoff, sowie die davon abgeleiteten Konsorten sind ebenso
unleserlich, wie überflüssig. Bei Flagfeldern, wie
sie von manchen APIs verwendet werden, sind Hex Konstanten und das addieren von
Binärzahlen vorzuziehen, soweit
man dies überhaupt benötigt. |
Sprunganweisungen vermeiden |
Unstruktur Anweisungen, wie GOTO und CABxx sind überflüssig und durch
strukturierte Elemente abzubilden. Der Gebrauch von
LEAVE und ITER ist eingeschränkt verwendbar, sollte aber kontrolliert
erfolgen. |
Prozeduren statt Subroutinen verwenden |
Subroutinen sind seit der Existenz von Prozeduren überflüssig und
werden nicht mehr verwendet. |
überflüssige Anweisungen weglassen. |
CALLP und EVAL sind überflüssig und sind nur Synonyme für "mach
es wirklich". Statt Extender und EVALR sollte man besser
Zwischenfelder, Casting und transparentes Errorhandling verwenden. |
Keine Fixformat Anweisungen benutzen. |
Es gibt keine erforderliche Anweisung mehr, die man nicht im Free Format oder
mit Built in Functions machen kann; selbst im
freien Format und bei den Built in Functions gibt es schon wieder
überflüssiges. Guter Programmierstil zeichnet sich durch
Einfachheit und Lesbarkeit aus; alles was kryptisch ist, ist auch schlecht. |