Softwareprojekt II (Stripgen)

Aus Nettundfroh
Wechseln zu: Navigation, Suche

Inhaltsverzeichnis

Milestone 1

Präsi

Milestone 2

Systementwurf

Nicht-Fachliche Komponenten

Rollentabelle:
Dienst Rolle Methode
Mitglied verwalten Administrator mitgliederVerwalten
Schuelerdaten importieren Administrator schuelerdatenImportieren
Anmelden ohne Rolle(Nutzer) anmelden
Passwort vergessen ohne Rolle(Nutzer) passwortVergessen
Passwort aendern jede Rolle passwortAendern
Abmelden jede Rolle abmelden
Rolle Verleiher aendern Lehrer rolleVerleiherAendern

Milestone 2

noch aendern

Milestone 3 (26.05.11)

noch zu erledigen

Milestone 4 (Implementierung und Abgabe, 13.07.11 gedruckt)

ToDo

CHANGELOG

Systemsteuerung:

  • System Starten (Initialisieren der Subsysteme)
  • Nutzer anmelden (FIETZ) JAVA:DONE
  • Aufbau des Menüs laut Rollen (alle Funktionalitäten, auch wenn nicht alle komplett realisiert werden) JAVA:DONE
  • Abmelden (FIETZ) JAVA:DONE
  • Testfälle bzw. Testdaten (MAX und Ergänzungen durch Jedermann) DONE
  • System Beenden

Nutzerverwaltung:

  • Anmelden (FIETZ) JAVA:DONE
  • Mitglieder Verwalten Ansicht (IGOR) JAVA:DONE
  • Mitglied Löschen (IGOR) JAVA:DONE
  • Mitglied Anlegen und Bearbeiten (ADRIAN, MANUEL) JAVA:DONE
  • Rolle Verleiher Ändern (TILO) JAVA:DONE
  • MitgliedSuchenDialog (MAX) JAVA:DONE
  • Funktionalität, die von der Ausleihe gefordert wurde (MAX) JAVA:DONE

UNSERE DEADLINE - 5.JULI (DIENSTAG)

Die Implementierung kann losgehen. Das Eclipseprojekt befindet sich in unserem svn im Ordner java.

Nach dem ersten Checkout muss -javaagent:lib/aspectjweaver.jar as VM-Argument in den Projekteigenschaften bei "Run/Debug Settings" gesetzt werden.

Außerdem ist jedem zu empfehlen sich zu Testzwecken eine lokale MySQL-Instanz mit Datenbank, Benutzer, Passwort = "lmv" einzurichten (wie in persistence.xml konfiguriert).

Vor jedem Arbeitsschritt sollte jeder sein Eclipseprojekt noch einmal updaten, damit keine unnötigen Merges vorgenommen werden müssen.

Die Anmeldung hat höchste Priorität. Sollte Fietz es bis Dienstag nicht schaffen, müsste diese Implementierung mit jemand anderem getauscht werden.

Sobald die Anmeldung implementiert ist, wird diese zusammen mit der Systemsteuerung hier für die anderen Gruppen herunterladbar sein, so dass diese ihre Implementierungen dagegen testen können.


Die folgenden Dokumente sollen bis zum 13.07.11 um 12.00 in gedruckter (und ohne Lupe lesbarer) Form im Sekretariat des Fachbereichs abgegeben werden:

• Das korrigierte Klassendiagramm (3-Tier Architektur) mit allen voll ausspezifizierten Klassen (inkl. Interface-Klassen und Paketen/Unterpaketen) und Assoziationen Ihres Subsystems (Aufgaben 4 + 5). Stellen Sie auch die Interface-Klassen aus den anderen Subsystemen dar, die von Klassen in Ihrem Subsystem realisiert werden.

• Komponentendiagramm, das die Kopplung der Komponenten über die vereinbarten Schnittstellen darstellt (Aufgabe 3).

• Die korrigierte, d.h. zum finalen Entwurf passende Beschreibung der implementierten Anwendungsfälle.

Bitte markieren Sie Ihre Dokumente deutlich mit Ihrem Gruppennamen.

Folgende Artefakte sollen in elektronischer Form abgegeben werden: • VP-UML Projekt (*.vpp) mit dem aktuellen Feinentwurf (korrigierter Milestone 3) und den zugehörigen korrigierten Sequenzdiagrammen zu allen Anwendungsfällen, die Sie implementieren müssen.

• Komplette Java-Sourcen für das gesamte System (Subsysteme + Systemsteuerung). D.h. ein gezippter Ordner mit allen Java-Dateien der Subsysteme in den entsprechenden (Paket-) Unterordnern. Ihr Subsystem sollte sich also über das Hauptmenü der Systemsteuerung bedienen lassen und korrekt mit den anderen Subsystemen interagieren.

• Eine „Start“-Klasse mit main-Routine, die das Subsystem Systemsteuerung initialisiert (die daraufhin die anderen Subsysteme initialisiert), so dass sich das ganze (Sub-)system aus Eclipse heraus starten lässt. Diese sollte von der Gruppe Nutzerverwaltung/Systemsteuerung zur Verfügung gestellt werden.

Die elektronischen Dokumente sollen bis zum 13.07.11 um 23.00 Uhr in den in den Unterordner Final des entsprechenden Gruppen-Ordners des Kurses Softwareprojekt II hochgeladen werden. Die Gruppenordner sind nur bis zu dem genannten Termin zugänglich.

Die Projektverteidigung wird am 19./21.7.11 stattfinden.

Views

Wir haben nun endlich einen Mechanismus zum Schließen aller geöffneten Fenster beim Abmelden.

Dazu implementiert jeder nichtmodale Dialog (außer Anmelden, PasswortVergessen) IDialog, meldet sich im Konstruktor beim MitgliederVerwaltenManager an und beim schließen wieder ab. Der MitgliedVerwaltenManager reagiert durch die MitgliedverwaltungFacade wie alle ISubSysteme auf den Aufruf der authenticationChanged()-Methode mit dem Schließen aller angemeldeten Dialoge.

Bei modalen Dialogen wie z.B. bei Nachrichtendialog muss dies nicht beachtet werden, da der fachlogische Programmablauf angehalten und das Mitglied nicht in der Lage ist den "abmelden"-Button zu klicken, bevor es nicht den Dialog beendet hat.

Um die Dialogmultiplizitäten zu berücksichtigen, haben die meisten unsere Dialoge per Konvention einen privaten Konstruktor und eine statische open(..)-Methode ohne Rückgabewert, die die Konstruktor-Argumente übergeben bekommt. Eine solche Methode kann die Multiplizität durch ein statisches Attribut - dessen Wert entweder null oder die Dialoginstanz ist - garantieren (0..1, Singleton). MitgliedFormular enthält aber z.B. ein statisches Map{mitglied => dialoginstanz}-Attribut (0..*, Multiton).

Jede Methode in MitgliedVerwaltenManager, die ein Mitglied verändert oder neu erstellt, muss die private Methode notifyObserver() aufrufen, die alle angemeldeten Observer-Instanzen (MitgliedSuchenDialog) mit dem Aufruf von update() über Änderung informiert und so das Neuladen der Mitgliederliste anstößt.

Deweiteren erbt IObserver jetzt von IDialog und der MitgliedVerwaltenManager enthält wie gehabt eine Liste von Observer(n), wobei MitgliedSuchenDialog jetzt der einzige Observer ist und einen Parental-IDialog als Konstruktor-Argument nimmt, um diesen über das Schließen des Fensters zu informieren, da MitgliedVerwaltenDialog und RolleVerleiherAendernDialog selbst kein eigenes Fenster haben, sondern mit dem MitgliedSuchenDialog arbeiten.

Systemsteuerungsschnittstelle - Hinweise an die anderen Gruppen

Top-Level-Package ist de.lmv.

Alle Teilsysteme implementieren de.lmv.system.ioc.ISubSystem.


ISubSystem sieht folgendermaßen aus:

+init() : void
+listBusinessMethodNames() : Map<String, String>
+authenticationChanged() : void

init() ist Initialisierer und wird nach der Injizierung aller Abhängigkeiten aufgerufen. Alle ISubSysteme sind Java-Beans im klassischen Sinne; d.h. sie haben einen Konstrukor ohne Argumente. Es wird dabei zwischen Instanziierung und Initialisierung unterschieden. Die SubSysteme werden zunächst instanziiert - damit sie bei bestehender gegenseitiger Abhängigkeit untereinander zugewiesen werden können - bevor sie durch den Aufruf von init() initialisiert werden.


Von listBusinessMethodNames() wird ein Mapping (Methodenname => Menülabel) als Rückgabewert erwartet. Diese Methode wird einmalig pro SubSystem beim Systemstart aufgerufen und das Ergebnis intern im SystemController zu einem Command Pattern gemapped um die enthaltenen Methoden zur Gesamtfunktionalität hinzuzufügen und später effizient auszuführen. Die Map kann also direkt in der Methode erzeugt werden. Dabei wird empfohlen eine LinkedHashMap<String, String> zu benutzen, sofern es von Interesse ist zu bestimmen in welcher Reihenfolge die Menüeinträge stehen.

Die Mapping-Implementierung ist so entworfen, dass jede Fehlimplementierung der ISubSystem-Schnittstelle bereits beim Systemstart eine Exception erzwingt.

Beim Aufruf eines Geschäftsprozesses über das Hauptmenü wird die Methode, deren Name beim Systemstart als Schlüssel in solch einer Map gesetzt wurde, per Reflection aufgerufen.

Eine solche Geschäftsprozessmethode hat weder Argumente noch einen Rückgabetyp.


authenticationChanged() wird aufgerufen, wenn sich ein Nutzer anmeldet oder ein Mitglied abmeldet.

Beim Aufruf dieser Methode sollten alle offenen Dialoge geschlossen werden [wenn nutzerverwaltung.getLoggedInMitglied() == null], damit der nächste Nutzer nicht in den Dialogen des letzten Mitglieds weiterarbeiten kann.


Dependency Injection funktioniert nur in ISubSystem-Instanzen (die beim Systemstart angemeldet wurden).

Ein abhängiges Feld kann privat sein.

Ein abhängiges Feld muss keinen Setter besitzen, da die Referenz per Reflection zugewiesen wird (keine "echte" Property, aber ist kürzer; Feldzugriff).

Ein abhängiges Feld wird mit der Java-Standard-Annotation javax.annotation.Resource annotiert.


Da wir mit einer Datenbank arbeiten und es nicht sinnvoll wäre, jedes ISubSystem eine eigene EntityManager-Instanz / Verbindung erstellen zu lassen, wird auch der EntityManager per @Resource-Annotation injiziert.


Beispiel:

public class MitgliederverwaltungFacade implements ISubSystem {

	@Resource
	private EntityManager entityManager; // wird injiziert
	@Resource
	private IMitgliederverwaltungAusleihe ausleihe; // wird injiziert
	private PasswortManager passwortManager;
	private MitgliedVerwaltenManager mitgliedVerwaltenManager;

	@Override
	public void init() {
		// Initialisierung kann erst hier stattfinden und nicht im Konstruktor,
		// weil im Konstruktor das Attribut entityManager == null

		IMitgliedDao mitgliedDao = new DBMitgliedDao(entityManager);
		mitgliedVerwaltenManager = new MitgliedVerwaltenManager(mitgliedDao);
		passwortManager = new PasswortManager(mitgliedDao);
	}

	@Override
	public Map<String, String> listBusinessMethodNames() {
		Map<String, String> res = new LinkedHashMap<String, String>();

		res.put("method1", "Meine tolle Methode Nr. 1");

		return res;
	}

//	/\==== von der Systemsteuerung gefordert
//	\/==== Fachlogik

	public void method1() {
		System.out.println("mtm2");
		ausleihe.pruefeOffeneAusleihvorgaenge(1); // hier würde es keine NullPointerException geben
	}
}

Zum Verständnis:

Die Systemsteuerung legt beim Programmstart ein Interface-Mapping aller von allen ihr bekannten ISubSystem-Instanzen implementierten Interfaces an, so dass bei der Dependency-Injection einem Feld eines bestimmten Interfacetypen der Wert aus dieser Map zugewiesen werden kann.

( Map{interfaceClass => ISubSystem-Instanz} )


Rollen

Um einen Ausgangszustand des Systems zu erzeugen liegt der Implementierung bereits eine Installationsmethode für Beispieldaten bei. Dabei wird ein Mitglied mit Name "admin" und Rollen Rolle.MITGLIED sowie Rolle.ADMINISTRATOR erzeugt und Rollendefinitionen aus der Datei roles.properties in die Datenbank gespielt. Diese Datei sieht bisher folgendermaßen aus und ist von den anderen Gruppen zu ergänzen:

Mitglied=abmelden,passwortAendern
Administrator=mitgliederVerwalten
Medienverwalter=
Verleiher=
Schüler=
Lehrer=rolleVerleiherAendern

Transaktionen

Die Transaktion kann man allgemein nicht in ein DAO schreiben, da die DAO-Operationen ja nur Teiloperationen einer ganzen Transaktion sind.

Das Importieren von Mitgliedern ist beispielsweise eine Transaktion, kann sich aber u.a. aus mehreren mitgliedDao.create()-Aufrufen zusammensetzen.


2 Möglichkeiten:

  1. Transaktionen - im Code verteilt - fest codieren (EntityTransaction-Instanz in der Fachlogik; hässliche tx.begin()..tx.commit()-Anweisungen + dazugehörige Rollback- und Fehlerbehandlungen; Außerdem würde beim späteren Umstieg auf ein FileDAO oder OODBDAO das DAO-Konstrukt nicht mehr nützlich sein, da wir die gehardcodeten Transaktionen in den Geschäftsprozessen überarbeiten müssten)
  2. Wir nutzen AOP, definieren Transaktionen und Logging in Aspekten (können dabei gleich den EntityManager synchronisieren, falls mit mehreren Fenstern parallel darauf zugegriffen wird), haben sauberen Code und unsere Ruhe

Beispiel:

@Transaction
@CatchAndLog(message="Schreibvorgang fehlgeschlagen!")
public void writeSthToDB() {
    mitgliedDao.create(new Mitglied(..));
}

In diesem Beispiel würde normaler Weise weder ein Fehler geworfen, noch irgendetwas geschrieben werden, da die Ausführung nicht in einer geschlossenen Transaktion stattfindet.

Für mit @Transaction annotierte Methoden ohne Rückgabewert existiert aber ein Aspekt, der die Ausführung der Methode in einen tx.begin()..try..tx.commit()..catch..tx.rollback()-Block verlegt. Diese Annotation sollte auf der Methode mit dem kleinsten gemeinsamen Nenner einer Transaktion verwendet werden (2. Schicht, ausführende Methoden der SubSystem-Facade) und kann nicht geschachtelt werden.

Der Aspekt, der auf die @CatchAndLog(message="")-Annotation reagiert, fängt alle Exceptions in der annotierten Methode, logged im Logger und zeigt einen Dialog mit der annotierten Fehlermeldung an. Diese Annotation sollte allerdings nur in Boundary-Klassen verwendet werden. Darunter sollten Exceptions ausschließlich über das throws-Schlüsselwort nach oben verwiesen ("checked") (oder als RuntimeException erneut geworfen) werden, so dass Exceptionhandling nur in der obersten Schicht zu finden ist (übersichtlicher). Auch dieser Aspekt kann nur auf Methoden ohne Rückgabewert angewendet werden!

Man sollte bei der Benutzung von Annotationen im Allgemeinen vorsichtig sein und sie nicht zu häufig verwenden. Dadurch, dass eine Annotation nur durch ein interpretierendes Modul eine Funktion erhält, kommt es schnell zu Annotationsleichen, die keine Bedeutung haben, aber von der IDE oder vom Compiler nicht als Fehler erkannt werden können. Dann wird Code wieder unübersichtlich!

Das tolle an Aspekten hingegen ist, dass durch sie die Prinzipien Separation of Concerns (SoC) und Don't Repeat Yourself (DRY) erst richtig eingehalten werden können, da Fehlerbehandlung und Logging eigene Belange sind, die von den anderen Belangen (der Fachlogik) auf jeden Fall getrennt werden müssen. Das wiederholte Schreiben gleichartiger Fehlerbehandlungen oder Logs verstößt natürlich auch gegen DRY. Außerdem ist Code ohne etliche try-catch-Blöcke einfach besser lesbar und man kann sich auf die Fachlogik konzentrieren.

Durch AOP ist es überhaupt erst möglich Fehlerbehandlung und Logging nachträglich effizient zu warten und zu konfigurieren.

View						catch					@CatchAndLog
  |						 /\
  V						  |
Controller / Facade				[catch and throw]			@Transaction
  |						  |
  V						  |
Model / Datenhaltung				throw

Würde die endgültige Fehlerbehandlung in einer tieferen Schicht stattfinden, besteht die Gefahr, dass (im Laufe der Weiterentwicklung) undefinierte Zustände in ganzen Objekten oder Codeabschnitten entstehen.

Das fangen und erneute schmeißen von Exceptions macht zum einen die einheitliche Fehlerbehandlung (durch selbst definierte Exceptions) in der darüberliegenden Schicht möglich (bei uns nicht notwendig), zum anderen ist es (auch in unserem System) teilweise notwendig Exceptions zu fangen, wenn sie in einer Methode eines Interfaces auftreten, die diese Exceptions nicht in der throws-Klausel definiert (in ActionListener.actionPerformed() können z.B. nur RuntimeExceptions geworfen werden). Im letzten Fall ist es am saubersten die Exceptions, die gefangen werden müssen, zu fangen und eine RuntimeException(e) mit der gefangenen Exception als Ursache zu werfen.

Die RuntimeException in Java erbt zwar von Exception, ist aber ein besonderer Fall: Im Gegensatz zu allen anderen Throwablevererbungslinien müssen RuntimeExceptions nicht per throws-Klausel deklariert, sondern können "unchecked" geworfen werden. UnsupportedOperationException und IllegalArgumentException sind z.B. RuntimeExceptions.


Zum Verständnis:

Wer sich für AOP interessiert und dieses Konstrukt nachbauen will, kann hier die neueste Version vom AspectJ-Compiler downloaden.

Das Compilerrelease ist keine jar, die man als Bibliothek verwenden könnte, sondern einfach nur ein Archiv.

Für die hier beschriebene Vorgehensweise müssen ausschließlich die beiden libraries aspectjrt.jar und aspectjweaver.jar entpackt werden (nicht der Compiler).


Die @Transaction-Annotation ist eine zusätzliche Abhängigkeit aller SubSysteme und ist in de.lmv.system.annotation folgendermaßen definiert:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Transaction { }

Der zur @Transaction-Annotation gehörende Aspekt sieht z.B. folgendermaßen aus (keine unserer Implementierungen ist davon abhängig):

@Aspect
public class TransactionAspect {

	@Around("execution(@de.lmv.system.annotation.Transaction void *(..))")
	public void aroundCode(ProceedingJoinPoint joinPoint) throws Throwable {
		EntityManager em = SystemController.getEntityManager();
		EntityTransaction tx = em.getTransaction();

		synchronized(em) {
			tx.begin();

			try {
				joinPoint.proceed();
				tx.commit();
			} catch(Throwable e) {
				if (tx.isActive())
					tx.rollback();

				throw e;
			}
		}
	}
}

Weitere Beispiele des Join Point Matchings mit Annotationen können hier gefunden werden: http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations-pointcuts-and-advice.html.


Die genannten Aspekte sind global gültig, werden in der Systemsteuerung definiert und in META-INF/aop.xml registriert:

<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
	<aspects>
		<aspect name="de.lmv.system.aspect.TransactionAspect"/>
		<aspect name="de.lmv.system.aspect.LoggingAspect"/>
	</aspects>
</aspectj>

Die JVM wird dann mit dem aspectjweaver als javaagent gestartet, der sich im ClassLoader einnistet, von wo aus er zur Ladezeit dynamisch Proxies für die implementierten Klassen erstellt und an deren Stelle ausgibt.

AspectJ kann auch zur Compilerzeit eingesetzt werden und es gibt dafür auch eine eigene an Java angelehnte Sprache, die in Eclipse vollste Unterstützung findet, aber wer mehr dazu wissen will, der google.

Unser Programm wird nach seiner Fertigstellung schließlich folgendermaßen ausgeführt:

java -javaagent:/pfad/zur/aspectjweaver.jar -jar LMV.jar

In einer IDE können in den Projekteigenschaften VM-Options bearbeitet werden (bei Run). Dort wird demnach eingetragen:

-javaagent:/pfad/zur/aspectjweaver.jar

Im classpath sind letztendendes folgende Bibliotheken enthalten (EclipseLink JPA 2.0, MySQL-JDBC-Treiber, AspectJ-Laufzeitabhängigkeiten unserer Aspekte):

eclipselink-2.0.2.jar				\
eclipselink-javax.persistence-2.0.jar		 | DB (wird natürlich nicht für AOP benötigt, könnte auch Hibernate und nen anderer JDBC-Treiber sein)
mysql-connector-java-5.1.6-bin.jar		/
aspectjrt.jar

AN DIE AUSLEIHE

In eurem IAusleiheMitgliederverwaltung interface stehen u.a. die Methoden

+getMitglied(mitgliedsNr : int) : Mitglied
+getMitgliedDao(mitgliedsNr : int) : IMitgliedDAOAusleihe

IMitgliedDAOAusleihe enthält aber nur

+getMitglied(userId : int) : Mitglied

getMitgliedDao() muss wegfallen, da wir euch nicht in unserem System schreiben lassen wollen und das IMitgliedDAOAusleihe-Interface ohnehin nur die getMitglied()-Methode enthält, die bereits in IAusleiheMitgliederverwaltung steht.

Außerdem müssen in diesem Interface alle "Mitglied" mit "IMitglied" ersetzt werden (der Fehler ist vllt auch nur bei uns?!). Das ist schließlich die dritte und letzte gemeinsame Schnittstelle(Nutzerverwaltung, Ausleihe), nachdem IMitgliedDAOAusleihe wegfällt.


IMitglied enthält die Methode

+getMitgliedsNr() : int

Es ist anzunehmen, dass damit die Bibliotheksnummer gemeint ist.

Damit keine Dopplungen auftreten und die Bezeichner eindeutig bleiben, würden wir diese Methode in eurem Interface gerne in getBibliotheksnummer() umbenennen.


Korrektur:

IAusleiheMitgliederverwaltung

+getMitglied(bibliotheksnummer : int) : IMitglied

IMitglied

+getBibliotheksnummer() : int
+getKlasse() : String
+getName() : String
+getVorname() : String

Zur gleichzeitigen Implementierung für die Systemsteuerung der anderen Gruppe ...

  1. ... müsste vermutlich ein extra Konstruktor mit Argumenten oder entsprechende Setter für abhängige Properties in der Facade deklariert und das Vorgehen mit der anderen Systemsteuerung abgesprochen werden.
  2. ... müssen alle Transaktionen selbst hartcodiert werden und die Ausleihe dürfte keine @Transaction- und @CatchAndLog-Annotationen verwenden (solange die andere Gruppe kein AOP verwendet).


ACHTUNG, NOCH ZWEI ÄNDERUNGEN: IMitglied.getBibliotheksnummer() : Integer (anstelle von int, weil das bei uns auch mal null sein muss, wenn ihr es bekommt wird es aber niemals null sein)

Eine der beiden von uns geforderten Methoden hat sich folgendermaßen verändert, damit ihr sofort das Mitglied bekommt:

de.lmv.nutzerverwaltung.control.IMitgliederVerwaltungAusleihe.pruefeOffeneAusleihvorgaenge(mitglied : IMitglied) : void

Projektverteidigung (Dienstag, 19.07, 8:30 Uhr)

0. Teil: Programm zeigen

  • Einloggen
  • Mitglieder Verwalten (Anlegen, Bearbeiten, Löschen)
  • Rolle Verleiher Ändern
  • Abmelden / Beenden

1. Teil: Systemsteuerung

  • Generelle Struktur
  • Systemstart erklären
  • ISubSystem erklären

2. Teil: Nutzverwaltung

  • Was kann die Nutzverwaltung (Anwendungsfälle)
  • Wie setzt die NutzverwaltungFacade die Schnittstelle ISubSystem um
  • Details der Control Klassen
  • Sequenzdiagramme der implementierten Anwendungsfälle


"3.Teil: Reflektion"

  • Was haben wir bei der Implementierung noch an Problemen gefunden, die wir beim Entwurf nicht beachtet haben?
    • Schließen aller Fenster beim Abmelden.
    • Singleton/Multiton
    • etc. pp
  • Kommunikation
    • kein fester Ansprechpartner in anderen Gruppen --> Chaos
    • keine Programmierstandards
      • Look and Feel
      • System.exit ...
      • Design
      • etc. pp


 Der Punkt muss nicht umgesetzt werden, aber ich denke, sie findet so etwas ganz gut.
 Außerdem sollten wir noch auf die ACL und besonders auf die role.properties eingehen.
 "Rechte können geändert werden und werden durch einen Neustart aktiv. oder evtl. über einen FileListener"
 AOP darf auch nicht fehlen ... 
 Fietz


Aus Strippgens PDF:

Bauen Sie die Präsentation so auf, als würden Sie anderen Entwicklern Ihr System erläutern, d.h. setzen Sie kein Wissen über den Entwurf und die Implementierung voraus (wohl aber über die Anforderungen). Nutzen Sie für die Erklärung - unter anderem - geeignete UML-Diagramme. Jedes Gruppenmitglied sollte einen Teil der Präsentation übernehmen.

In der Präsentation sollten Sie auf die folgenden Dinge eingehen (die Auflistung stellt keine vorgegebene Reihenfolge dar):

  • Architektur des Systems sowie Schnittstellen zu anderen Subsystemen vorstellen, wichtigste Entwurfsentscheidungen anhand des Klassendiagramms erläutern.
  • Vorgehensweise in der Implementierungsphase, Arbeitsteilung, Werkzeuge, etc.
  • Vorführung der Funktionalität des Systems, d.h. zeigen, dass alle zu implementierenden Anwendungsfälle funktionieren
  • Anhand des Source-Codes die Umsetzung der Anwendungsfälle erklären.

Nach der Präsentation werden Ihnen Fragen zu Ihrem Entwurf und der Implementierung gestellt.

Gliederung / Aufteilung

Media:SWPJ_INHALTE.doc

Master Semester 2