Java Code QualityRegeln für gute Java-ProgrammeTreffpunkt Semicolon, 22.02.2011, GFU Cyrus AGJens Seekamp, GEDOPLAN GmbH
Java Code Quality – ein ganzheitlicher AnsatzAgenda  Software-Qualität  Regel 1: System-Dekomposition und Build-Prozess  R...
Software-Qualität  Strukturierung (System, Komponente, Schicht, Paket, Klasse, Methode,  Anweisung)  Einheitlichkeit (Gene...
Regel 1: System-Dekomposition und Build-Prozess  System-Dekomposition     Zerlegung des Software-Systems in Komponenten   ...
Architektur einer „kleinen“ Java-EE-Anwendung                                            Projekt PRAGSYS:                 ...
Architektur einer „großen“ Java-EE-Anwendung                                         Projekt BDE:                         ...
Regel 1: System-Dekomposition und Build-Prozess  Build-Prozess     „Bauen“ des Software-Systems aus seinen kompilierten   ...
Maven-Multi-Projekt für Java-EE-Anwendung<project><groupId>de.gedoplan.bde</groupId>                  <project><artifactId...
Regel 2: Schichten-Architektur  Zerlegung in 3-Schichten-Architektur      Präsentations-Schicht (GUI)      Fachlogik-Schic...
Schichten-Architektur einer Java-EE-Anwendung                                                10
Sicherstellung der Schichten-Architektur  häufige Verletzungen der Schichten-Architektur     „Überspringen“ einer Schicht ...
Sicherstellung mit Checkstyle-Modul „Import Control“                                                       12
Regel 3: Modell-getriebene Entwicklung  aus einem „Modell“ generierter Java-Code ist     strukturiert     einheitlich     ...
„klassische“ Modell-getriebene EntwicklungGenerierung                        @Entity                                   pub...
Generierung von XML-Zugriffsklassen (1)Generierung  für die Umwandlung Java-Objekte      XML-Dokumente  (Marshalling / Unm...
Generierung von XML-Zugriffsklassen (2)                                              XJC                            @XmlAc...
Generierung eines Formel-ParserGenerierung  eines Parser für arithmetisch-logische Formeln  aus einer kontextfreien Gramma...
Regel 4: inkrementelle Entwicklung - Randbedingungen   package de.aoksystems.pragsys.service.pruefkern;   import de.aoksys...
Regel 4: inkrementelle Entwicklung - Tipps  Implementierung: konkret beginnen und schrittweise verfeinern  erst „in die Ti...
Regel 5: Richtlinien und statische Code-Analyse  ein Team von SW-Entwicklern ist heterogen (Berufs-/Projekterfahrung,  Pro...
Regel 5: Richtlinien-Katalog (Beispiele)  Standard-Konventionen für Java der Firma Sun  deutsche Bezeichner für Klassen, A...
Regel 5: Werkzeuge für statische Code-Analyse  Idealfall: für jede Richtlinie gibt es eine aktivierte Analyse-Regel  und u...
Beispiel: Code-Bereinigung mittels Checkstyle / Review               (5)   Import-Organisation, Formatierung              ...
Regel 6: integrierter, automatisierter Test  Software-Test hat zwei Zielsetzungen      im Java-Code möglichst viele Fehler...
Regel 6: Test-Konzeption für Java-(EE)-Anwendungen  Schritt 1: Entwicklertest für wichtige Klassen und Methoden     „Stand...
Regel 6: Bibliothek der automatisierten Testfälle  Zusammenfassung aller automatisierten Testfälle aus Schritt 1 bis 5  zu...
Regel 7: Refactoring und Regressionstest  Fehler und Qualitätsmängel des Java-Code werden laufend  festgestellt durch     ...
Beispiel: Redundanz-Beseitigung und Kapselung                   Aufdecken von redundantem Java-Code mit                   ...
Regel 7: Regressionstest im Rahmen der CI  Wahrung der funktionalen Korrektheit nach Refactorings wird durch  den Regressi...
Nächste SlideShare
Wird geladen in …5
×

Java Code Quality: Gute Software braucht guten Code - Regeln für verständliche und wartbare Java-Programme

4.187 Aufrufe

Veröffentlicht am

Kurzbeschreibung

Softwarequalität ist keine Spracheigenschaft. In jeder noch so guten Programmiersprache kann man schlechte Programme schreiben – sogar in Java. Herr Seekamp, Senior Consultant bei der GEDOPLAN GmbH, macht in diesem Vortrag anhand von Fallbeispielen aus seinen Projekten deutlich, was verständlichen und wartbaren Code ausmacht, welche Regeln man dafür beherzigen sollte und welche Analysewerkzeuge dabei unterstützen können.

Inhalt
Regeln für guten Java-Code
Statische Code-Analyse
Refactoring
Werkzeuge zur Sicherung der Qualität

Veröffentlicht in: Technologie
0 Kommentare
0 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

Keine Downloads
Aufrufe
Aufrufe insgesamt
4.187
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
5
Aktionen
Geteilt
0
Downloads
40
Kommentare
0
Gefällt mir
0
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie

Java Code Quality: Gute Software braucht guten Code - Regeln für verständliche und wartbare Java-Programme

  1. 1. Java Code QualityRegeln für gute Java-ProgrammeTreffpunkt Semicolon, 22.02.2011, GFU Cyrus AGJens Seekamp, GEDOPLAN GmbH
  2. 2. Java Code Quality – ein ganzheitlicher AnsatzAgenda Software-Qualität Regel 1: System-Dekomposition und Build-Prozess Regel 2: Schichten-Architektur Regel 3: Modell-getriebene Entwicklung Regel 4: inkrementelle Entwicklung Regel 5: Richtlinien und statische Code-Analyse Regel 6: integrierter, automatisierter Test Regel 7: Refactoring und Regressionstest 2
  3. 3. Software-Qualität Strukturierung (System, Komponente, Schicht, Paket, Klasse, Methode, Anweisung) Einheitlichkeit (Generierung, Muster) Richtlinien-Konformität (statische Programm-Analyse) Verständlichkeit (Funktionalität / Logik der Software-Elemente) Lesbarkeit (Bezeichner, Formatierung, ...) Dokumentation, Kommentare (JavaDoc) Korrektheit und Stabilität (funktionaler Programm-Test) Leistungsfähigkeit (Performanz, Last), Benutzerfreundlichkeit Wartbarkeit (Fehlerbehebung, Change Requests) Erweiterbarkeit (neue Anforderungen) 3
  4. 4. Regel 1: System-Dekomposition und Build-Prozess System-Dekomposition Zerlegung des Software-Systems in Komponenten eine Komponente kapselt einen Funktionsbereich (Schnittstelle vs. Rumpf) eine Komponente basiert oftmals auf einer Implementierungs- Technologie (z. B. EJB) eine Komponente ist i. d. R. ausführbar 4
  5. 5. Architektur einer „kleinen“ Java-EE-Anwendung Projekt PRAGSYS: Prüfsystem für Statistiken der GKV 5
  6. 6. Architektur einer „großen“ Java-EE-Anwendung Projekt BDE: Betriebsdatenerfassung für Fertigungsindustrie 6
  7. 7. Regel 1: System-Dekomposition und Build-Prozess Build-Prozess „Bauen“ des Software-Systems aus seinen kompilierten Komponenten dabei wird je Komponente ein Build-Artefakt erstellt Werkzeuge für den Build-Prozess Build-Prozess wird vollständig mit Maven 3.x durchgeführt Java-Compiler der IDE ist (theoretisch) überflüssig Continuous Integration wird mit Hudson realisiert (z. B. Nightly Build) 7
  8. 8. Maven-Multi-Projekt für Java-EE-Anwendung<project><groupId>de.gedoplan.bde</groupId> <project><artifactId>bde</artifactId><version>1.0.0</version> <parent> <groupId>de.gedoplan.bde</groupId><modules> <artifactId>bde</artifactId> <module>bde-common</module> <version>1.0.0</version> <module>bde-comp-mitarbeiter</module> </parent> <module>bde-comp-zeiterfassung</module> <module>bde-web</module> <artifactId>bde-comp-mitarbeiter</artifactId> <module>bde-ear</module> <packaging>ejb</packaging></modules> <project> <project> <parent> ... <parent> ... <artifactId>bde-web</artifactId> <artifactId>bde-ear</artifactId> <packaging>war</packaging> <packaging>ear</packaging> <dependencies> ... <artifactId>bde-comp-mitarbeiter ... ... <artifactId>bde-web ... 8
  9. 9. Regel 2: Schichten-Architektur Zerlegung in 3-Schichten-Architektur Präsentations-Schicht (GUI) Fachlogik-Schicht (Geschäftsfälle, Dienste, Fachklassen) Datenhaltungs-Schicht (Speicherung der Objekte, RDBMS) zusätzlich oftmals „übergreifende“ Schichten fachliches Klassenmodell (Entitäten) Basis-Dienste und –Klassen (z. B. Ausnahmen, Meldungen) Schichten-Zerlegung ist möglich auf Ebene des Software-Systems auf Ebene der Komponenten 9
  10. 10. Schichten-Architektur einer Java-EE-Anwendung 10
  11. 11. Sicherstellung der Schichten-Architektur häufige Verletzungen der Schichten-Architektur „Überspringen“ einer Schicht (Präsentation Datenhaltung) „umgekehrte“ benutzt-Beziehung (Datenhaltung Fachlogik) falsche Zuordnung von Implementierung Realisierung von fachlicher Logik in Dialogklassen erkennbar in Benutzung von Fachklassen anstelle von Dienst-Schnittstelle Sicherstellung durch Spezifikation von erlaubten benutzt-Beziehungen nicht erlaubten benutzt-Beziehungen 11
  12. 12. Sicherstellung mit Checkstyle-Modul „Import Control“ 12
  13. 13. Regel 3: Modell-getriebene Entwicklung aus einem „Modell“ generierter Java-Code ist strukturiert einheitlich korrekt und stabil Code-Generierung steigert außerdem die Effizienz der Software-Entwicklung die Wartbarkeit des Software-Systems 13
  14. 14. „klassische“ Modell-getriebene EntwicklungGenerierung @Entity public class Land des fachlichen Klassenmodells { @Id (Entitäten) private String isoCode; private String name; als POJO-Klassen mit JPA- public Land() Annotationen {} public String getIsoCode() aus UML-Klassenmodell (z. B. { return this.isoCode; } Enterprise Architect) public void setIsoCode(String code) { this.isoCode = code; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } } 14
  15. 15. Generierung von XML-Zugriffsklassen (1)Generierung für die Umwandlung Java-Objekte XML-Dokumente (Marshalling / Unmarshalling) als POJO-Klassen mit JAXB-Annotationen aus XML-Schema (z. B. XMLSPY) mit dem JAXB-Schema-Compiler (Java Architecture for XML Binding) 15
  16. 16. Generierung von XML-Zugriffsklassen (2) XJC @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "Satzart_Ctp", propOrder = {"verfahren", "zeitraumAb", "zeitraumBis"}) public class Satzart implements Serializable { @XmlElement(name = "Verfahren", required = true) private String verfahren; public String getVerfahren() { return verfahren; } public void setVerfahren(String daten) { verfahren = daten; } 16
  17. 17. Generierung eines Formel-ParserGenerierung eines Parser für arithmetisch-logische Formeln aus einer kontextfreien Grammatik mit dem Parser-Generator JavaCC (Java Compiler Compiler) TOKEN: { | < PLUS: "+" > 12 * x + 5 ... | < MINUS: "-" > } void Addition(): { Token t = null; StringBuilder sb = new StringBuilder(); } + { Multiplikation() ( ( t = <PLUS> Multiplikation() ) { sb.append(t.image); } | ( t = <MINUS> Multiplikation() ) { sb.append(t.image); } * 5 )* { jjtThis.jjtSetValue(sb.toString()); } } 12 x 17
  18. 18. Regel 4: inkrementelle Entwicklung - Randbedingungen package de.aoksystems.pragsys.service.pruefkern; import de.aoksystems.pragsys.bo.statistik.Statistik; import de.aoksystems.pragsys.bo.pruefung.Pruefergebnis; @Stateless public class PruefServiceBean implements PruefService { /** * Diese Methode prüft eine Statistik, die an das Prüfsystem * übergeben wurde, und liefert das Prüfergebnis zurück. */ public Pruefergebnis pruefeStatistik(Statistik s) {...} } 18
  19. 19. Regel 4: inkrementelle Entwicklung - Tipps Implementierung: konkret beginnen und schrittweise verfeinern erst „in die Tiefe“, später „in die Breite“ implementieren (Prototyping, depth-first) möglichst frühe Rückkopplung gleichzeitige Erstellung von Unit-Tests Review durch Projekt-Kollegen Demonstration für Benutzer Grundsätze beachten (vgl. http://www.clean-code-developer.de) immer objektorientiert und „sauber“ möglichst einfach (KISS), redundanzfrei (DRY), ... „Software ist (fast) nie fertig.“ (evolutionäre Entwicklung, TODOs) 19
  20. 20. Regel 5: Richtlinien und statische Code-Analyse ein Team von SW-Entwicklern ist heterogen (Berufs-/Projekterfahrung, Programmierstil) für einheitlichen, lesbaren, kommentierten usw. Java-Code sind Entwicklungs-Richtlinien unabdingbar Richtlinien-Katalog zusammengefasst im Entwickler-Handbuch Beschreibung der Richtlinie (ggf. mit Motivation, Zielsetzung) Positiv- und ggf. Negativ-Beispiele (Do‘s and Dont‘s) Umfang des Programm-Code und Anzahl der Richtlinien erfordern automatisierte Überwachung Werkzeuge für die statische Code-Analyse z. B. Checkstyle, FindBugs, SonarJ 20
  21. 21. Regel 5: Richtlinien-Katalog (Beispiele) Standard-Konventionen für Java der Firma Sun deutsche Bezeichner für Klassen, Attribute, Methoden etc. verwenden Konstanten bestehen nur aus Großbuchstaben, Ziffern und dem Unterstrich "_" anstatt null ein Array der Länge 0 zurück geben falls eine Exception geworfen wird, muss sie protokolliert werden mehrmals benötigte Programmlogik wird in eine separate Methode bzw. Klasse ausgelagert Reflection darf nicht verwendet werden 21
  22. 22. Regel 5: Werkzeuge für statische Code-Analyse Idealfall: für jede Richtlinie gibt es eine aktivierte Analyse-Regel und umgekehrt für „kleine“ Projekte sollte ein Code-Analyse-Werkzeug reichen für „große“ Projekte und Vollständigkeit müssen ggf. mehrere Code- Analyse-Werkzeuge parallel eingesetzt werden erhöhter Konfigurationsaufwand Problem der Mehrfach-Meldung von Verletzungen Standardisierung / Wiederverwendung des Richtlinien-Kataloges und der Werkzeug-Konfiguration (über Projekt- und Abteilungsgrenzen) Werkzeuge machen Reviews durch Software-Architekten oder erfahrene Entwickler nicht überflüssig 22
  23. 23. Beispiel: Code-Bereinigung mittels Checkstyle / Review (5) Import-Organisation, Formatierung (4) Namenskonventionen, Bezeichner, for (3) JavaDoc, Anweisungs-Struktur, Kommentare (2) try-catch, Parameterprüfung (1) Ausnahmebehandlung, Logging „Nice“ 23
  24. 24. Regel 6: integrierter, automatisierter Test Software-Test hat zwei Zielsetzungen im Java-Code möglichst viele Fehler aufdecken Korrektheit der Anwendung demonstrieren Test ist integraler Bestandteil der Software-Entwicklung, und nicht nur nachgelagert (vgl. testgetriebene Entwicklung, test-first) Test dient zum Nachweis der dynamischen, funktionalen Korrektheit des Java-Code (dies ist mit statischer Code-Analyse nicht möglich) Fokus liegt auf der Realisierung von automatisierten Tests dafür Einsatz von Java-Test-Frameworks und –Werkzeugen 24
  25. 25. Regel 6: Test-Konzeption für Java-(EE)-Anwendungen Schritt 1: Entwicklertest für wichtige Klassen und Methoden „Standard“-Framework JUnit 4.x Schritt 2: Realisierung einer Testdaten-Verwaltung Nutzung dedizierter Test-Datenbank(en) explizite Testdaten-Erzeugung mittels Java (DBUnit, XMLUnit) Schritt 3: Integrationstest der Service-Schicht per JUnit-Testclient gegen den Application-Server (remote) mittels z. B. OpenEJB innerhalb der IDE (embedded) Schritt 4: „automatisierter Abnahmetest“ der GUI-Clients Werkzeug abhängig von GUI-Technologie und –Bibliothek z. B. QF-Test (alle), Selenium (Web), Abbot (Swing) Schritt 5: Test nicht-funktionaler Anforderungen (Performanz, Last) 25
  26. 26. Regel 6: Bibliothek der automatisierten Testfälle Zusammenfassung aller automatisierten Testfälle aus Schritt 1 bis 5 zu einer Test-Bibliothek als Test-Suites gemäß JUnit (JUnit-Integration aller Werkzeuge / Frameworks vorausgesetzt) hierarchische Strukturierung der Test-Suites gesamte Test-Bibliothek auf Entwicklungsrechner lokal ausführbar 26
  27. 27. Regel 7: Refactoring und Regressionstest Fehler und Qualitätsmängel des Java-Code werden laufend festgestellt durch werkzeuggestützte, automatisierte Tests werkzeuggestützte, statische Code-Analyse direkte Notwendigkeit für Fehlerbehebung und Mängelbeseitigung bedingt oftmals Refactoring, d. h. weitergehende, strukturelle „Umbau-Arbeiten“ nach einem Refactoring ist der Java-Code fehlerbereinigt und / oder qualitativ besser ist die Gesamt-Funktionalität unverändert 27
  28. 28. Beispiel: Redundanz-Beseitigung und Kapselung Aufdecken von redundantem Java-Code mit Checkstyle-Modul „Strict Duplicate Code“ Auslagern der Code-Redundanz in eine separate Klasse dadurch gleichzeitig Kapselung der Verwendung des JAXB-Framework 28
  29. 29. Regel 7: Regressionstest im Rahmen der CI Wahrung der funktionalen Korrektheit nach Refactorings wird durch den Regressionstest sichergestellt Regressionstest ist der Test des gesamten Java-Code auf Basis der Test-Bibliothek Zusammenfassung aller automatisierten, qualitätssichernden Maßnahmen in der Continuous Integration (Hudson): Integrations-Build (Subversion, Maven) Generierung der Programm-Dokumentation (JavaDoc) statische Code-Analyse (Checkstyle, ...) Regressionstest (JUnit, ...) auf Basis der Test-Bibliothek Messung der Test-Überdeckung (Cobertura) Deployment auf QS-Umgebung (für manuelle Tests) 29

×