HTML5 Icon 10 Jahre Thailand 

Projekt kalkulierter thailändischer Kalender Tag (13-18)

by Nudels


Posted on Donnerstag Mai 21, 2020 at 09:25AM in Technik - Programmierung


Die Chronologie systematischer Software-Entwicklung




Ein Projektüberblick – Systemarchitektur und Programmierung (Tag13-18)



Nun ist es soweit, wir stellen eine gute Vorarbeit unter Beweis und starten mit der Programmierung. Wir werden unsere Entwicklungsumgebung einrichten, Tests mit Junit entwickeln, begleitende Tests durchführen, Fehler analysieren und das Szenario für Änderungswünsche prüfen. Wenn keine Katastrophen eintreten, werden wir mit dem Zeitplan von 5 Tagen hinkommen. Wie in den Berichten davor, beschränke ich die Dinge auf das Wesentliche.


Entwicklungsumgebung einrichten


Wir benötigen Maven als Manager für unsere Abhängigkeiten. Da ich Eclipse-Fan bin, benutze ich das Maven-plugin m2e. Öffne unter Help den Marketplace und suche direkt nach m2e. Ist das Tool einmal installiert, kannst Du direkt Mavenprojekte erstellen und verwalten. Wir brauchen des weiteren Zugriff auf einen Mysql-Server. Dieser kann auch lokal installiert sein. Wir brauchen für dieses Projekt nur den Zugang um unsere Datenbank zu installieren, den Rest erledigen Maven und Spring. Ebenso brauchen wir den Zugang zu einem Servlet-Container. Auch dieser kann lokal installiert sein. Ich benutze den Apache Tomcat. Dieser wird über File- New – other – Server – Apache in die Entwicklungsumgebung eingebunden. Ein Zugang zu einem Version-Control-System ist für einen Entwickler ein muss. Ich benutze nach wie vor Subversion. Das Eclipse-Plugin findet man ebenfalls im Marketplace, z.B.: Subclipse. Um Spring brauchen wir uns erstmal nicht zu kümmern, auch das erledigt Maven für uns. Wahrscheinlich wird die größte Zahl der Leser diese Werkzeuge bereits einsetzen.  




Maven im Eclipse Marketplace



Junit Tests entwickeln –Qualitätsmanagement


Das Kapitel Tests mit Junit werde ich hier überspringen. Es wird in der ausführlichen Dokumentation zu lesen sein.


MVC-Mechanik aufbauen und testen


Maven-Projekt konfigurieren


Ich bin Spring Neuling und habe bereits 10 Brutto Tage nutzen können, um mich einzulesen und ein wenig auszuprobieren. Jetzt wollen wir gezielt ein Spring Projekt anlegen und dieses mit unseren Vorhaben füllen. Was jetzt folgt, ist zugeschnitten auf die oben beschriebene Entwicklungsumgebung. Es sollte ohne große Umstände auf andere Systeme übertragbar sein.
Wir legen ein Maven Projekt an: File – New - other - Maven - Maven Project.
Da wir die „archetype selection“  benötigen unbedingt den Skip-Selektor aus schalten!
Wir geben „WEB“ in die Suche ein, wählen dieses „archetype" und machen mit next weiter. Die Group-Id entspricht unserem package-Namen z.B.: de.niweau.tfkt. Die Artifact ID entspricht unserem Projektnamen z.B.: Thaikalender_R2. … und finish.



Im Projekt-Explorer finden wir unser Projekt wieder und es ist leider mit einem Fehler markiert, der sich auf die index.jsp bezieht. Der Fehler ist plausibel und wird in 2 Schritten korrigiert:




index.jsp



1.    Wir öffnen unsere pom.xml und fügen in der Sektion build unter final_name  das gewünschte Compiler-plugin ein:




Beim Compiler-plugin ist ein absoluter Pfad erlaubt




Die Sektion project schliessen wir mit der Propertie für Interpreter und Encoding:




Encoding




      Speichen und schliessen und mit alt F5 das Projekt aktualisieren.



2.     Wir öffnen die web.xml löschen alles, und fügen den Namespace, die Deklaration und die richtige Version des Web-Modules durch den folgenden Eintrag ein:



web.xml





Wir öffnen die „Project properties" und gehen auf den „buildpath" und fügen mit „add libraries" die Server Runtime hinzu, z.b.: Apache Tomcat V7. … und finish. Speichern schließen und einmal alt F5.

Es erscheint eine neue Fehlermeldung: Das Web-Modul 3.0 kann nicht geladen werden. Es gibt hierzu eine Reihe von Lösungsvorschlägen, von denen mich nur diese hier überzeugt hat:

Wir öffnen die Project properties und gehen auf das Deployment Assembly. Mit Add fügen wir den „Java Build Path Entries" „Maven Dependencies" hinzu . Nach einem „Maven project Update" checken wir die „project Facets" und sehen die richtige Java Version und das richtige Web-Module. Das scheint plausibel.

Es gibt wohl Konfigurationen, bei denen dieser Ablauf nicht auf Anhieb klappt. Aktualisiere das Projekt einmal ohne Web-Module und danach mit Web-Modul, das schafft Abhilfe.

Wir öffnen jetzt nochmal die pom.xml und fügen alle weiteren dependencies hinzu, die wir benötigen. Das sind: „spring-core, spring-web, spring-webmvc, javax.servlet-api, jstl, spring-jdbc, mysql-connector."





alle Abhängigkeiten




Danach machen wir wieder ein „Maven Update Project". Bis auf eine Abhängigkeit haben wir unsere Umgebung jetzt in Maven angepasst.



Die folgende Abhängigkeit können wir erst hinzufügen, wenn wir sie programmiert haben. Um den Maven-Part abzuschliessen, nehme ich sie hier vorweg. Wenn unsere core-lib: „zr-somostr1.jar" fertig ist, kopieren wir sie gleich in den finalen Ordner, das ist unter „WEB-INF" das Verzeichnis „lib". Die pom.xml wird um die dependency erweitert:




die eigene lib



Spring-Projekt konfigurieren


Damit ist Maven für unser Projekt konfiguriert. Achte auf die Versionen! Nehme nie absolute Pfadangaben für das Web-Modul, sondern Variablen. Wir checken nochmal unsere Konfiguration mit Maven „Update Project" und sehen, das Projekt ist auf dem aktuellsten Stand und ohne Fehlermarkierungen. Ein letzter Hinweis: Maven-Update-Project hat den Short-Cut „alt F5", was normalerweise auch funktioniert. Wenn sich aber das Projekt-Auswahlfenster nach „alt F5" nicht öffnet, findet auch kein Update statt. Beherzige alle Fehlermeldungen und nimm auch die Warnings war. Versuche selbst analytisch Lösungen zu finden. In der Regel klappt es so.


Alle Konfigurationsdateien enthalten projektspezifische Einzelheiten, deshalb ergibt es wenig Sinn, diese zu kopieren. Selber machen übt.


Die Datenbank


Unsere Datenbank ist ein echtes Leichtgewicht. Wir benutzen sie nur, um Daten bequem ändern zu können, ohne dabei den Source-Code anzufassen. Der wesentliche Punkt ist allerdings: Die Tabellen sind ein exaktes Abbild der korrespondierenden Klassen. Wir werden die Relation über DAO bedienen und auf Schwergewichte wie Hibernate oder Eclipse-Link verzichten. Als Vorlage dient das ER-Model aus dem Kapitel Datenmodel und Algorithmen. Es ist wesentlich, um alle Zeichen darstellen zu können, auch die Datenbank im UTF-8 Mode einzurichten: Standard Kollation -> UTF8_general_ci.


Die Springkonfiguration


Die Springkonfiguration hat ja bereits mit den Abhängigkeiten in Maven begonnen. Jetzt kommt ein bisschen Handwerk und ein bisschen Fine-Tuning. Wir kontrollieren unseren Projekt-Verzeichnis-Baum  und ergänzen, was noch nicht vorhanden ist, bis er genauso aussieht, wie in der folgenden Abbildung. Wir arbeiten nur innerhalb des rot markierten Bereichs:




Der Projektbaum




Der rote Bereich repräsentiert den Spring-Entwicklungsbereich. Innerhalb des roten Bereiches gibt es noch 2 Teilmengen: Eine dünne grüne Linie repräsentiert den View-Bereich und die Konfigurationsdateien des Web-MVC-Archetypes. Die dünne blaue Line ist unsere Kreativ-Zone. Hier finden wir das M und das C, des Archetypes. Wir arbeiten uns von oben nach unten durch. Unterhalb von main sollte der Folder java sein. Ab hier legen wir für jeden Abschnitt unseres packages einen eigenen Folder an. Im letzten Folder gibt es standardmäßig nur die 4 Folgenden:
•    Model: Hier kommen unsere Model-Klassen rein
•    DAO: Hier kommen die Interfaces und die Impl.-Klassen für die Datenbankzugriffe rein.
•    Manager: In diesem Ordner sind die Klassen der Business-Logik zuhause.
•    Controller: Hier stehen die Klassen, die den Datenfluss steuern.
Wir wechseln in die grüne Teilmenge und befinden uns im Verzeichnis webapp. Er beherbergt die Ordner resources und WEB-INF. In resources gehören alle Dateien, die unsere Views beeinflussen, das sind Style-sheets, Images und Java-Script-Dateien. Hier packen wir auch die Bootstrap-Lib rein. Der Ordner WEB-INF enthält zwei Folder und 2 xml-Dateien. Von oben nach unten:
•    Lib – In lib liegen alle libraries, die nicht direkt von Spring verwaltet werden. Hier kommt unsere core-lib zr-somost rein.
•    Views – In diesem Ordner befinden sich in der Regel Dateien des Typs <name>.jsp. Sie sind als Views im MVC eingebunden.
•    Dispatcher-servlet.xml -  Dieses ist die Konfigurationsdatei des dispatcher-servlets, das uns Spring generiert. Die Datei kann auch anders benannt werden, muss dann in der web.xml entsprechen bekannt gemacht werden.
•    Web.xml – Die web.xml haben wir bereits angefasst. Wir vervollständigen sie jetzt mit der Konfiguration und Deklaration des dispatcher-servlets:




fertige web.xml



Das, was wir sehen, erschreckt uns erst mal nicht, denn es sieht aus wie die Einrichtung eines x-beliebigen Servlets mit Context-Parametern und einem Listener. Dieses eine Servlet steuert allerdings unser gesamtes Projekt. Um das zu verstehen, schauen wir uns die Context-Parameter genauer an, die in der Datei dispatcher-servlet.xml zu finden sind.


Das Dispatcher-Servlet




dispatcher-servlet.xml




Damit es schön übersichtlich bleibt, habe ich die einzelnen Abschnitte mit Überschriften versehen. Von oben nach unten:
•    Namespaces und Deklarationen
Diese sind Abhängig von dem verwendeten Archetype
•    Bindings
Erweiterung des Contextpath um zusätzlichen Resourcen, hier: Die Ordner unserer Styles, Images, etc.
•    Dao  Klassen
Declaration und Konfiguration des Datenbankzugriffs.
•    Bean Deklarationen
Declaration der Manager Beans mit Klassenpfad
•    Bean Mapping
Declaration  und Mapping der Controller Beans
•    Adapter Handler
Adapter Handler die nicht im Default-Umfang des Archetypes sind
•    Views.
Standard-Declaration der Views

Aus diesen Informationen baut spring uns die Architektur einer Web-Anwendung. Schön, dass wir uns darum nicht selber kümmern müssen ;-)


Als letzten Schritt können wir in den Vorbereitungen schon die leeren Files für Klassen und Views anlegen. Das sieht dann so aus:






Die Core-Lib zr-somost-r1 (Zeitrechnung-SonneMondSterne-Release1)



Unsere Entwicklungsumgebung  ist fertig konfiguriert und wir starten das Codeing. Wir erinnern uns an unser Daten-Modell und bauen exakt danach unter Berücksichtigung von Datenfluss und Abhängigkeit unsere Corelib. Die Entwicklung dieser lib ist reines Handwerkszeug. Sie könnte genauso in C oder Fortran programmiert werden, deshalb reduziere ich die Beschreibung hier auf das wesentliche.




Klassenstruktur im einfachen Mavenprojekt




Für die lib wird ein eigenes einfaches Mavenprojekt angelegt. Wir finden hier die Klassen aus unserem Datenmodell, die im Springprojekt nicht zu sehen waren. Im Detail von oben nach unten:
•    Astrowert – enthält alle notwendigen astronomischen Kennzahlen
•    GregCalender – generiert ein Kalenderblatt nach gregorianischem Muster
•    Konst
•    Lunissolar – enthält das Regelwerk des Lunissolarkalenders und die Arithmetik der Sonne
•    Monat – enthält Namen, Kurznamen und die Regeln zur Berechnung der Neujahrsdistanz
•    Mond – enthält die Regeln zur Berechnug der Mondphasen, Mondzahl und die Mondarithmetik
•    Wochentag – enthält die Namen, Kurznamen und das Regelwerk zur Ermittlung des Wochentages
•    Zeit – ist die umfangreichste Klasse. Zeit enthält die gesamte Arithmetik für Berechnungen im gregorianischen Kalender.
Damit wir zr-somost-r1 nahtlos in unser Springprojekt integrieren können, verfolge ich die gleiche Architektur. Es fehlen einzig die Views. Wir haben Pojo-, Manager- und Controller-Klassen. Die Gründe, warum ich diese Klassen auslagere liegen, zum Einen darin, dass ich diese lib wiederverwenden möchte, und zum Anderen, dass ich eine Umgebung brauche, in der ich schnelle und unbefangene, entwicklungsbegleitende Tests durchführen kann. Zum Testen habe ich ein Konsolentool programmiert, mit dem ich entwicklungsbegleitend schnell einfache Methoden, Massentests und Summentests durchführen kann. Dieses Tool ist nicht für die abschliessenden Tests mit Junit vorgesehen. Es dient nur der Qualitätskontrolle während der Entwicklung.




Test-Konsole





Mond


Der Mond ist als belastbare Konstante in der Astronomie ein unzuverlässiger Partner. Einzig seine synodische Periode eignet sich dazu mit einfachen Mitteln tagesgenaue Berechnungen durchzuführen. Aus dieser Erkenntnis entwickele ich die folgenden Methoden im MondManager:


public MondManager(){
//////////////////////////////////////////////////////////////////////////////////
//
// Initialisieren
//
//////////////////////////////////////////////////////////////////////////////////

//dynamische Liste aus der Datenbank laden und hier setzen - Ist notwendig um mit den aktuellen Daten zu arbeiten   
public Mond setAstrowerte(List<Astrowert> astrowertList){
//statische Liste nur zum Testen geeignet   
public void setAstrowerte(){
//Einen Mond initialisieren -
public Mond setMond(int mondzahl, String mondphase, int tag, int monat, int jahr       
//////////////////////////////////////////////////////////////////////////////////
//
// Formate und Transformationen
//
////////////////////////////////////////////////////////////////////////////////////Extrahiert Datum aus Mond

public String getDatum3(Mond m){
//Es wird nur das Datum von Mond nach Zeit übertragen
public Zeit MondDatum2Zeit(Mond m){
//Es wird nur das Datum von Zeit nach Mond übertragen
public Mond ZeitDatum2Moon(Zeit z){

////////////////////////////////////////////////////////////////////////////////////
// Vollmond Reihen: next.... last.... first..... etc
//
//////////////////////////////////////////////////////////////////////////////////
//Daten des Bezugs Mondes

public Mond getVerlMond(){
//Daten des erste VollMond Mondes zum verlässlichen  Mond <--> im Lunissolarkalender startet das Jahr mit Neumond !!!
public Mond getFirstFullMoon(){
//Der erste Vollmond des Mondkalenders für das Jahr - erliegt im Jahr davor, zwischen November und Dezember
// !!!!!!!!!!        getestet ---- OK --------        !!!!!!!!!!

public Mond getFirstFullMoon(int jahr,boolean debug){
//Liefert den Mond in X Monden nach m1 ---- zuverlässlicher als nextMoon
// !!!!!!!!!!        getestet ---- OK --------        !!!!!!!!!!

private Mond MondHintermMond(Mond m1, int monde){
//Liefert den Mond in X Monden vor m1 ---- zuverlässlicher als lastMoon
private Mond MondVorMond(Mond m1, int mzahl){
//VollMond nach dem Datum des eingegebenen Mond (von Vollmond zu Vollmond)
// !!!!!!!!! Achtung bei Mehrfachaufruf Rundungsfehler in den Anbruchtagen !!!!!!!!!!!!!!!

private Mond nextFullMoon(Mond m){
//Vollmond vor dem Datum des eingegebenen Mond (von Vollmond zu Vollmond)
private Mond lastFullMoon(Mond m){
//Die Liste aller Vollmonde eines Jahres
// !!!!!!!!!!        getestet ---- OK --------        !!!!!!!!!!

public List<Mond> getVollMondListe(int jahr){

//////////////////////////////////////////////////////////////////////////////////
//
// Specials
//
//////////////////////////////////////////////////////////////////////////////////

//Frühjarzvollmond (...für die Berechnung von Ostern) ist der Vollmond im März (Tag- und Nacht-Gleiche ) normalerweise der 4. Mond
public Mond fruehjahrVollmond(int Jahr){
// Ostertermin für eine Jahr
public String Ostern(int Jahr){
//////////////////////////////////////////////////////////////////////////////////
//
// Berechnungen
//
//////////////////////////////////////////////////////////////////////////////////
//Liefert den Mond zum Datum

public Mond MondToday(int tag, int monat, int jahr, boolean debug){
//Liefert die anteilige % einer Mondperiode
private double whichMond(int tag, int monat, int jahr){
// Interpretiert Ergebnis von whichMond als Phasenpartikel
public String whichMondInter(double i){       
public String DatumNachMondzahl(int mondzahl, int jahr){
public String DatumNachMondzahUndPhase(String mondphase,int mondzahl, int jahr,int vorlauf,int nachlauf,boolean debug){
// Meton Korrektur - Schalttage werden hier korrigiert
private Zeit einfacheMetonKorrektur(Zeit zs, int zj){
////////////////////////////////////////////////////////////////////////////
//
// Notwendiger Krimskrams
//
/////////////////////////////////////////////////////////////////////////////

public int getMondPhase(String dat){
private double mphase(double jd){
private double frac(double x){
private double sinG(double x){
private double cosG(double x){
private double ydate(double t)


Zeit


Warum entwickele ich die Zeitarithmetik neu? Die Antwort ist recht einfach: Zum Einen benötige ich Algorithmen, die bis auf Einem niedrigen Level belastbar zu Testen sind und zum Anderen brauche ich Algorithmen, die skalierbar sind. Hier kommen die Methoden des Zeitmanagers.


public class ZeitManager {
public ZeitManager(){

///////////////////////////////////////////////////////////////////////
//
//Stunde Minute Sekunde
//
///////////////////////////////////////////////////////////////////////

//Umrechnung Stunde Minute Sekunde --> Dez
private double sms_dec(String z){
//Umrechnung Dez --> Stunde Minute Sekunde 
private String sms(double z){
//Differenz SMS <--> SMS       
// Summe    SMS <--> SMS       
// Format SMS --> 01:01:01
// Format SMS --> 01:01
// Gibt das Datum heute zurück
// !!!!!!!!!!        getestet ---- OK --------        !!!!!!!!!!

public String formatHeute() {
///////////////////////////////////////////////////////////////////////   
//
// Schaltjahr   
//   
////////////////////////////////////////////////////////////////////////   
// Schaltjahr Test
// !!!!!!!!!!        getestet ---- OK --------        !!!!!!!!!!

public boolean schaltjahr(int nJahr){   
// Datum vor, oder nach Schalttag   
// !!!!!!!!!!        getestet ---- OK --------        !!!!!!!!!!

public boolean vorgregschaltteil(int monat,int tag){
// Schalttagekorrektur - wieviele Schalttage liegen zwischen 2 Datum (Reihenfolge egal)
// !!!!!!!!!!        getestet ---- OK --------        !!!!!!!!!!

public int schalttage(Zeit d1,Zeit d2){
////////////////////////////////////////////////////////////////////////
//
// Jahr Monat Tag
//   
////////////////////////////////////////////////////////////////////////   
//Checke Datum 1 größer Datum 2
// !!!!!!!!!!        getestet ---- OK --------        !!!!!!!!!!

public boolean checkgroesser(Zeit d1,Zeit d2){
//das Ergebnis ist für grösser true und für < und = false;
//Umrechnung Jahr Monat Tag --> Dez

public double datum2dez(Zeit z,boolean sk){
//Umrechnung Dezimal Datum --> Jahr Monat Tag -- Mit Korrektur Vor und Nach Schalttag
public Zeit dez2datum(double x,boolean sk){
//Umrechnung Datum tt.mm.yyyy --> Zeit
public Zeit string2datum(String x){
//Datums String tt.mm.yyyy in Zeit-bean einlesen
//Differenz Datum <--> Datum sk true -> für Schaltjahrsbereinigung -- in der neuen Version nicht einstellbar
// !!!!!!!!!!        getestet ---- OK --------        !!!!!!!!!!

public int diffdatum(Zeit d1, Zeit d2,boolean sk){
// Ergebnis ist die Differenz in Tage zwischen Datum 1 und Datum 2
//Differenz Datum minus Tage --> Datum sk true -> in der neuen Verion ohne Effekt
// !!!!!!!!!!        getestet ---- OK --------        !!!!!!!!!!
// Ergebnisse noch auf eventuelle Schalt-Nachkorrekturen prüfen !!!!!!!!!!

public Zeit datumminustage(Zeit d1, double tage,boolean sk){       
//Differenz Datum minus Tage --> Datum sk true -> in der neuen Verion ohne Effekt
public Zeit datumplustage(Zeit d1, double tage,boolean sk){
//Distanz vom JahresAnfang - Schaltjahr wird berücksichtigt
public int neujahrdistanz(int tag, int monat, int Jahr){
//Distanz vom JahresAnfang - Schaltjahr wird berücksichtigt
//Tage in Tage - Monate - Jahre Format zu Bezugs Zeitpunkt D1

public Zeit tage2ddmmyyyy(Zeit d1,double tage){
//////////////////////////////////////////////////////////////////////////
//
// Formate
//
//////////////////////////////////////////////////////////////////////////
//Format Datum --> wtk tt.mm.yyyy

public String datum4(int tag, int monat, int jahr,String wtk){
//Format Datum --> tt.mm.yyyy
public String datum3(int tag, int monat, int jahr){
//Format Datum --> tt.mm aus integer
public String datum2(int tag, int monat){
//Format Datum --> tt.mm aus Zeit
public String datum2ausZ(Zeit z){
//////////////////////////////////////////////////////////////////////////
//
//Wochentage
//   
//////////////////////////////////////////////////////////////////////////   
//Gausswert 1.1

 public int getGaussWert( int jahr){
//errechnet aus dem Jahr und dem Tagesdelta zum 1.1. die Wochentagszahl nach
//Gausswert    x.x

public int getGaussWertX( int jahr, int deltatage){
//errechnet aus dem Jahr und dem Tagesdelta zum 1.1. die Wochentagszahl nach
//Gausswert Wochentag

public String getWochentag(int i){
//Gausswert Wochentag Kurzform
public String getKurzWochentag(int i){
//letzter Wochentag im Monat --> Eingabe Wochentag(Sa, So, ....) und Monat --> Ausgabe Zeit
public Zeit letzterWTim(String wt, int monat,int jahr){
//erster Wochentag im Monat --> Eingabe Wochentag(Sa, So, ....) und Monat --> Ausgabe Zeit
public Zeit ersterWTim(String wt, int monat, int jahr){

// Der erste Werktag nach dem Wochenende - in der Regel der Montag
public String ersterMOnachWE(Zeit WE,String wt){
// erster Wochentag nach einem Datum - z.B.: Ostern erster Sonntag nach Frühjahrsvollmond
public String ersterwtnachDatum(String wt,String dat){
////////////////////////////////////////////////////////////////////////////
//
//Notwendiger Krimskrams
//
/////////////////////////////////////////////////////////////////////////////

public int runden(double wert, double limit){
//normalerweise ist limit 0.5.


An dieser Stelle ziehen wir Bilanz. Wir haben unsere Entwicklungsumgebung vollständig und funktionabel eingerichtet und getestet. Wir haben die Core-Lib angelegt und die ersten beans mit ihren Mangern und Controllern programmiert und partiell getestet. Wir können wesentliche Berechnungen im Bereich Zeit und Mond durchführen. Hierzu habe ich 2 Tage benötigt.


Feiertage


Wir kommen jetzt zum Spring Part der Anwendung. Da wir von den Möglichkeiten, die Spring bietet nur wenige, aber dafür wesentliche benutzen, mache ich mir erstmal keine Sorgen um den Zeitplan. Es ist wichtig, sich nochmal ins Gewissen zu rufen, wie funktioniert die MVC-Architektur, welche einzelnen Aufgaben haben die Komponenten und welche Rolle spielt das Dispatcher-Servlet dabei. Es ist nicht so schwer.
Mit der Feiertagsliste als Beispiel gehe ich jetzt eine Komponente vollständig durch:


Dispatcher-Servlet


Die Dao-Klasse wird deklariert, der Manager wird deklariert und am Ende wird noch das Mapping mit dem Controller verknüpft. Das sind die Context-Parameter für das Dispatcher-Servlet, die die Feiertagsliste bilden.




3 Einträge als Context-Parameter





Die View feiertagList:



Im roten Kasten finden wir die Namespaces, die wir benutzen. Unbedingt darauf achten, dass Pageencoding und charset auf UTF-8 gesetzt sind, sonst können wir keine thailändischen Zeichen darstellen. Im grünen Kasten sehen wir die Erweiterung des Contextpaths auf unsere Resourcen. So können wir auf styles und Images zugreifen. Der blaue Kasten enthält die Feiertagliste, die vom Controller kommt. Wir sehen noch ein wenig JSTL, das ich nur für kleinere Fallunterscheidungen benutze. Das macht die View dynamischer und wenn der Umfang im Rahmen bleibt, ist die Übersichtlichkeit auch nicht gefährdet.




... UTF-8 beachten




Das Model



Das Model Feiertag ist hier in ganzer Länge zu sehen. Es ist die einfachste Javaklasse, die es gibt. Sie enthält nur Get- und Set-Methoden und 2 Konstruktoren: Einen leeren für die DAO-Klasse und einen Standard-Konstruktor mit allen Eigenschaften. Es ist eigentlich in Java selbstverständlich, dass der erste Buchstabe nach get und set in diesen Methoden ein Großbuchstabe ist, aber der Hinweis an dieser Stelle spart Fehleranalysen, denn Spring nimmt dieses sehr genau.




Das Model Feiertag



Das DAO Interface

Das Interface ist klassisch nach CRUD deklariert. Ich benutze in diesem Release allerdings nur getALL(). So bin ich schon mal für die Zukunft vorbereitet. Es müssen dann natürlich alle Methoden in der Impl. Überschrieben werden, auch wenn es zunächst minimale dummies sind.



Das Interface...





... und die Implementierung



Der Controller


Wie im Dispatcher deklariert, stellt der Controller die Get- und Set-Methoden für den Manager plus ein Adapter-Handler bereit. Dieser Request-Handler ist ein Standard-Handler für den Archetyp, er muss nicht separat deklariert werden. Wir schauen uns den Teil im roten Rahmen an: Hier benutzen wir die Methoden, die uns der Manager zur Verfügung stellt, um Daten mit der View auszutauschen.


Die Parameter-Übergabe





Der Manager



Nachdem wir das Model vollständig gesehen haben, will ich niemanden den kilometerlangen Source Code des Managers zumuten. Im roten Kasten sehen wir die Methoden für den Controller (s.o.) Der grüne Kasten enthält die DAO-Klassen, die injiziert werden („don’t call us – wait until we call you“). Die blauen Kästen stammen aus unserer Corelib zr-somost-r1.




Die Parameter-Übergabe



Fazit


Das ist Alles in Allem weniger Arbeit, als die Entwicklung des Cores. Wir kommen also für die Entwicklung von 2 Views, 2 Controllen, 2 Models und 2 Managern locker über die Zeit. Was passiert eigentlich, wenn in diesem Moment noch Änderungswünsche kommen? Das scheint überhaupt kein Problem zu sein. Wenn es nur um die MVC-Mechanik geht, sind neue Präsentationsdaten zügig ergänzt – eine Sache von weniger als einer Stunde Arbeit, dank der strikten und übersichtlichen Architektur von Spring. Wenn Teile des Cores ergänzt, oder geändert werden müssen, ist dieses nach Aufwand der Aufgabe zu bewerten. Die Entwicklung des Cores findet außerhalb des Archetypes statt und kann anschließend sehr einfach wieder in den Archetype integriert werden.  


...es geht demnächst weiter mit Bootstrap und css ;-)



No one has commented yet.

Leave a Comment

HTML Syntax: Ausgeschaltet