Ein Textadventure AIP Aufgabe 2 14.05.2009 Fabian Bergfeld Patrick Boeckhoven Christian Haberland Benjamin Jochheim Liem Nguyen.

Slides:



Advertisements
Ähnliche Präsentationen
der Universität Oldenburg
Advertisements

Objektorientierte Programmierung
Objektorientierte Programmierung
Kapselung , toString , equals , Java API
Progwerkstatt JAVA Klasse, Objekte, Konstruktoren, Methoden
Java: Objektorientierte Programmierung
Java: Dynamische Datentypen
FH-Hof Servlets Richard Göbel. FH-Hof Konzept Servlets werden auf der Server-Seite durch ein Formular aufgerufen werten die Eingaben aus einem Formular.
Java: Grundlagen der Objektorientierung
FH-Hof Fehlerbehandlung Richard Göbel. FH-Hof Konzept Fehler können mit dem Operator throw einer übergeordneten Funktion signalisiert werden. Parameter.
SWITCH - Anweisung.
Verzweigung oder bedingte Anweisung Weiter mit PP.
Ein Beispiel in Java.
Klassenvariable. Da man für jede Kuh bzw. jede Henne auf dem Markt den gleichen Preis für ein Liter Milch, bzw. den gleichen Preis für ein Ei bekommt,
Konstruktoren.
Objekte werden als Adressen (Referenzen) übergeben. Dies führt manchmal zu unerwarteten Ergebnissen...
Interface bzw. Schnittstelle anschaulich: Hüllenklasse
FOR Anweisung. Aufgabe : Ausgabe aller ganzen Zahlen von 0 bis 100 auf dem Bildschirm.
DO...WHILE Anweisung.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (05 – Elementare Datenstrukturen) Prof. Th. Ottmann.
Informatik II, SS 2008 Algorithmen und Datenstrukturen Vorlesung 6 Prof. Dr. Thomas Ottmann Algorithmen & Datenstrukturen, Institut für Informatik Fakultät.
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 7 Claudio Moraga, Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
Programmieren mit JAVA
Programmieren mit JAVA
PKJ 2005/1 Stefan Dissmann Methoden (Motivation) Idee: Identische Programmabschnitte zusammenfassen und mit einem Namen versehen Vorteile: Übersichtlichkeit.
PRJ 2007/1 Stefan Dissmann Motivation Problem: gleiche Datenstrukturen werden für verschiedene Objekte gebraucht: z.B. Listen von Studierenden, Kunden,
PKJ 2005/1 Stefan Dissmann Ausblick Es fehlen noch: Möglichkeiten zum Strukturieren größerer Programme Umgang mit variabler Zahl von Elementen Umgang mit.
Zusammenfassung Vorwoche
PKJ 2005/1 Stefan Dissmann Zusammenfassung Vorwoche Methoden sind mit einem Namen versehene Programmabschnitte besitzen Rückgabetyp, Namen, Parameterliste.
Listen Prof. Dr. Christian Böhm in Zusammenarbeit mit Gefei Zhang
Projektplan: Fachgebiet Software Engineering Übersicht © Albert Zündorf, Kassel University.
DVG Interfaces. DVG mehrfache Vererbung 4 Mehrfache Vererbung ist die Ableitung einer Klassen von mehreren anderen Klassen. –farbigerPunkt.
DVG Einführung in Java1 Einführung in JAVA.
07-GraphischeObjekte Graphische Objekte in EMMA301Paint.
Abstrakte Klassen, Interface
DVG Klassen und Objekte
Java in 9 Folien Besser: Online-Buch Go to Java 2.
Einführung in die Programmierung Klassendefinition und Objekte
Seite 1 Interface - Konzept Ein Interface führt einen neuen Datentyp ein: interface Frau {... } Das Interface enthält Deklarationen ( keine Definitionen.
Einfach verkettete Listen (OOP)
Ein Textadventure AIP Aufgabe Fabian Bergfeld Patrick Boeckhoven Christian Haberland Benjamin Jochheim Liem Nguyen.
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
Vom Umgang mit Daten. public void myProgram() { int[] saeulenWerte = new int[world.getSizeX()]; for (int i = 0; i < saeulenWerte.length; i++) { saeulenWerte[i]
OOP-Begriffe Abstraktion Modellieren Klasse Objekt Attribute Methoden
Einfach und doppelt verkettete Listen in JAVA by Jens Weibler
EPROG Tutorium #3 Philipp Effenberger
Learning By Doing Ausnahmebehandlung Exceptions (Ausnahmebehandlung) Typische Fehlverhalten zur Laufzeit: s. Buch S. 287ff -Verwendung von null-Objekten.
Programmiervorkurs WS 2014/15 Instanzmethoden
Java-Kurs - 8. Übung Besprechung der Hausaufgabe.
Java-Kurs - 6. Übung Besprechung der Hausaufgabe
Alois Schütte Advanced System Programming 2 Interprozeßkommunikation  2.1 JVM Ablaufumgebung  2.2 Java Native Interface (JNI)  Verwendung von.
OOP-Begriffe Abstraktion Modellieren Klasse Objekt Attribute Methoden
Ausnahmen Vorlesung besteht aus zwei Teilen Programmierung (4 SWS)
A Workshop About this chapter General description Units Time Schedule
Java-Kurs - 6. Übung Besprechung der Hausaufgabe
Objektorientierte Programmierung (OOP)
Java Programme nur ein bisschen objektorientiert.
Tutorium Software-Engineering SS14 Florian Manghofer.
Tutorium Software-Engineering SS14 Florian Manghofer.
Tutorium Software-Engineering SS14 Florian Manghofer.
Tutorium Software-Engineering SS14 Florian Manghofer.
Konstruktoren.
„Was du ererbt von Deinen Vätern hast, erwirb es, um es zu besitzen.“
Es gibt Klassen, die mit der Entwicklungsumgebung ausgeliefert werden
1. Die rekursive Datenstruktur Liste 1
Implementieren von Klassen
 Präsentation transkript:

Ein Textadventure AIP Aufgabe Fabian Bergfeld Patrick Boeckhoven Christian Haberland Benjamin Jochheim Liem Nguyen

Entwürfe Dr.Little schlecht,besser Unterschiede schlecht ->besser Erweiterung um oben,unten Erweiterung Stories 1.0 Statische Sicht Dynamische Sicht Verteilungssicht Fachliche Sicht Erweiterung Stories 2.0 Unterschiede zu Stories 1.0

Feste Eingänge -> Erweiterungen sind schwierig Verwendung öffentlicher Attribute class Raum { public String beschreibung; public Raum nordausgang; public Raum suedausgang; public Raum ostausgang; public Raum westausgang Verletzung -> InformationHiding

Private wird verwendet -> Attribute versteckt Attribute nur über Getter und Setter zu erreichen gibKurzbeschreibung() ‏ gibLangeBeschreibung() ‏ setzeAusgang() ‏ class Raum { private String beschreibung; private HashMap ausgaenge; // die Ausgänge dieses Raums

Nicht alle Parameter werden verwendet -> Interface zu breit Schlecht für Erweiterungen -> Parameterliste müsste erweitert Bei mehrmaligen Setzten eines Raumes, kann kein Null mehr für einen Raum gesetzt werden public void setzeAusgaenge(Raum norden, Raum osten, Raum sueden, Raum westen) { if(norden != null) ‏ nordausgang = norden;... -> InformationHiding -> hohe Kopplung

Ausgang Norden und Osten bleiben beim zweiten Aufruf erhalten!!! // Aufruf 1: setzeAusgaenge(ausgangNorden,ausgangOsten, ausgangSueden, ausgangWesten) // Aufruf 2: setzeAusgaenge(null,null, ausgangSueden, ausgangWesten);... Fehler beim wiederholten Aufrufen. Beispiel:

alle Parameter werden verwendet Ausgaenge nur durch Setter zu setzen Beliebige Richtung können eingegeben werden (-) Keine Absicherung der Richtung (Dubbleten) ‏ public void setzeAusgang(String richtung, Raum nachbar) { ausgaenge.put(richtung, nachbar); }

Ausgänge werden als HashMap implementiert -> mehrere Ausgänge möglich Nachteile: (-) richtung als String ->Eingabe falscher Ausgänge Abgeschwächt bei Verwendung von StringKonstanten private HashMap ausgaenge; // die Ausgänge dieses Raums.... ausgaenge.put(richtung, nachbar);... draussen.setzeAusgang("east", hoersaal); draussen.setzeAusgang(“East", labor); Besser: draussen.setzeAusgang(EAST, labor);

Direkter Zugriff auf Klassen-Attribute Man muss das innere von Raum kennen Es kann die Abfrage eines Attributs vergessen werden private void willkommenstextAusgeben(){... if (aktuellerRaum.nordausgang != null) System.out.print("north "); if (aktuellerRaum.ostausgang != null) System.out.print("east "); if (aktuellerRaum.suedausgang != null) System.out.print("south "); if (aktuellerRaum.westausgang != null) System.out.print("west "); -> Information Hiding -> hohe Kopplung

Redundanter Code Genauso wie in willkommenstextAusgeben() ‏ Gefahr bei Änderungen private void wechsleRaum(Befehl befehl) {... System.out.println("Sie sind " + aktuellerRaum.gibBeschreibung()); System.out.print("Ausgänge: "); if (aktuellerRaum.nordausgang != null) System.out.print("north "); if (aktuellerRaum.ostausgang != null) System.out.print("east "); if (aktuellerRaum.suedausgang != null) System.out.print("south "); if (aktuellerRaum.westausgang != null) System.out.print("west ");

Spiel greift über gibLangeBeschreibung() auf Raum, um Ausgänge auszugeben Spiel braucht keine Interna von Raum wissen public String gibLangeBeschreibung() ‏ { return "Sie sind " + beschreibung + ".\n" + gibAusgaengeAlsString(); } private String gibAusgaengeAlsString() ‏ { String ergebnis = "Ausgänge:"; Set keys = ausgaenge.keySet(); for(Iterator iter = keys.iterator(); iter.hasNext(); ) ‏ ergebnis += " " + iter.next(); return ergebnis; }

Greift direkt auf interne Attribute Codeänderung bei Erweiterung von Richtung private void wechsleRaum(Befehl befehl) ‏ {..... Raum naechsterRaum = null; if (richtung.equals("north")) naechsterRaum = aktuellerRaum.nordausgang; if (richtung.equals("east")) naechsterRaum = aktuellerRaum.ostausgang; if (richtung.equals("south")) naechsterRaum = aktuellerRaum.suedausgang; if (richtung.equals("west")) naechsterRaum = aktuellerRaum.westausgang;..... Information Hiding

Ermittlung des nächsten Raumes liegt jetzt in Raum Spiel braucht keine Interna von Raum wissen Spiel greift über aktuellerRaum.gibAusgang(richtung) auf nächsten Raum zu class Raum {.... private HashMap ausgaenge; // die Ausgänge dieses Raums... public Raum gibAusgang(String richtung){ return (Raum)ausgaenge.get(richtung); }

Feste Befehlsliste -> Feste Bestandteile von Veränderlichen trennen Schlecht für Erweiterung Ausgabe auslagern -> trennen von Logic private void hilfstextAusgeben() { System.out.println("Sie haben sich verlaufen. Sie sind allein."); System.out.println("Sie irren auf dem Unigelände herum."); System.out.println(); System.out.println("Ihnen stehen folgende Befehle zur Verfügung:"); System.out.println(" go quit help"); } (Open Closed Principle) ‏

Ausgabe aller gültigen Befehle wurde an Parser übergeben Parser besitzt alle Befehlswoerter Gültige Befehle werden einer Stelle definiert (in Befehlswoerter) ‏ private void hilfstextAusgeben() {.... System.out.println("Ihnen stehen folgende Befehle zur Verfügung:"); parser.zeigeBefehle(); } class Parser { public void zeigeBefehle() ‏ { befehle.alleAusgeben(); }

Wird nur von verarbeiteBefehl() aufgerufen, daher sollte die Schnittstelle kleiner sein (nur den Raum übergeben) ‏ private void wechsleRaum(Befehl befehl) {

„Look“ wird angenommen, obwohl es nicht spezifiziert ist. Dadurch dass „look“ nicht erwartet wird, wird es nicht abgefangen Unerwartete Funktionalität class Befehlswoerter { // ein konstantes Array mit den gültigen Befehlswörtern private static final String gueltigeBefehle[] = { "go", "quit", "help", "look" };

"Das Befehlswort sollte 'null' sein, wenn dieser Befehl als nicht vom Spiel erkannt gekennzeichnet werden soll. Schlecht: Datenparameter haben eine Doppelbedeutung public Befehl(String erstesWort, String zweitesWort) { befehlswort = erstesWort; this.zweitesWort = zweitesWort;}.... public boolean istUnbekannt() { return (befehlswort == null); } Single Responsibility Principle

Liefert das Befehlswort (das erste Wort) dieses Befehls. Wenn der Befehl nicht verstanden wurde, ist das Ergebnis 'null'. Schlecht: Datenparameter haben eine Doppelbedeutung Verbesserung: Exceptions im Fehlerfall public String gibBefehlswort() ‏ { return befehlswort; }

Ausgaben (hier via println) sowie das einlesen via Buffered Reader sollten von dem eigentlichen Parsen entkoppelt werden. public Befehl liefereBefehl() {... System.out.print("> "); // Eingabeaufforderung..... BufferedReader eingabe = new BufferedReader(new InputStreamReader(System.in));..... eingabezeile = eingabe.readLine();... Single Responsibility Principle Trennung von Funktion und Interaktion

Dr.Little schlecht und besser werden um oben+unten erweitert

class Raum {... public Raum oberausgang; public Raum unterausgang;.... public void setzeAusgaenge(Raum norden, Raum osten,, Raum oben, Raum unten Raum sueden, Raum westen, Raum oben, Raum unten) { if(oben != null) ‏ oberausgang = oben; if(unten != null) ‏ unterausgang = unten;... public void setzeAusgaenge(Raum norden, Raum osten, Raum sueden, Raum westen) {, null, null this.setzeAusgaenge(norden, osten, sueden, westen, null, null); }

Class Spiel {... private void raeumeAnlegen(){ Raum aussichtsturm, keller; //Erweiterung oben+unten.... aussichtsturm = new Raum("im Aussichsturm der Uni"); keller = new Raum("im Keller der Uni");.... draussen.setzeAusgaenge(null, hoersaal, labor, cafeteria); hoersaal.setzeAusgaenge(null, null, null, draussen); cafeteria.setzeAusgaenge(null, draussen, null, null); labor.setzeAusgaenge(draussen, buero, null, null, null, keller); buero.setzeAusgaenge(null, null, null, labor, aussichtsturm, null); keller.setzeAusgaenge(null, null, null, null, labor, null); aussichtsturm.setzeAusgaenge(null, null, null, null, null, buero);

Class Spiel {... private void willkommenstextAusgeben() {... if (aktuellerRaum.oberausgang != null) System.out.print("upstairs "); if (aktuellerRaum.unterausgang != null) System.out.print("downstairs ");.... private void wechsleRaum(Befehl befehl) { if (richtung.equals("upstairs")) naechsterRaum = aktuellerRaum.oberausgang; if (richtung.equals("downstairs")) naechsterRaum = aktuellerRaum.unterausgang;... if (aktuellerRaum.oberausgang != null) System.out.print("upstairs "); if (aktuellerRaum.unterausgang != null) System.out.print("downstairs ");

Class Spiel {... private void raeumeAnlegen(){... aussichtsturm = new Raum("im Aussichsturm der Uni"); keller = new Raum("im Keller der Uni");.... labor.setzeAusgang("north", draussen); labor.setzeAusgang("east", buero); labor.setzeAusgang("downstairs", keller); //Erweiterung; oben+unten buero.setzeAusgang("west", labor); buero.setzeAusgang("upstairs", aussichtsturm); //Erweiterung; oben+unten //Erweiterung; oben+unten keller.setzeAusgang("upstairs", labor); aussichtsturm.setzeAusgang("downstairs", buero);

Erweiterung von Dr. Little-besser um Stories 1.0

Demonstration

Erweiterung von Dr. Little-besser um Stories 2.0

Demonstration

Stories 2.0: GUI

Vielen Dank!