Fallstudie: Videothek-Verwaltung Aufgabenstellung Abrechnung einer Videothek: 3 Arten von Videos Normalpreis Neuerscheinung Kindervideos 2 + 1, 50 pro Tag ab dem 3. Tag 3 pro Tag 1, 50 plus 1, 50 pro Tag ab dem 4. Tag Bonuspunkte pro Ausleihung Normalpreis 1 Punkt Neuerscheinung 1 Punkt + 1 Zusatzpunkt, ab 2 Tage Kindervideo 1 Punkt Gewünschte Ausgabe: Kunde: Max Glotzmann Star Trek 3,50 Terminator VII 6,00 König der Löwen 3,00 Gesamtpreis 12,50 Bonuspunkte 4 UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.1
Klasse Movie (Filme) reine Datenklasse class Movie { public static final int regular = 0, newrelease = 1, children = 2; private String title; private int kind; Movie - title - kind gettitle() setkind(n) getkind() public Movie (Sting s, int n) { title = s; kind = n; public String gettitle () { return title; public void setkind (int n) { kind = n; public int getkind () { return kind; get- und set-methoden machen es leichter, private Daten später zu ändern. erlauben es, read-only-attribute zu modellieren (z.b. title). kosten allerdings Effizienz und machen Programm größer. UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.2
Klasse Rental (Ausleihung) Ausleihvorgang eines Films durch einen Kunden. Ebenfalls reine Datenklasse Rental - movie - days class Rental { private Movie movie; private int days; getmovie() getdays() public Rental (Movie m, int d) { movie = m; days = d; public Movie getmovie () { return movie; public int getdays () { return days; UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.3
Klasse Customer (Kunde) Pro Kunde wird sein Name und die von ihm ausgeliehenen Filme gespeichert. class Customer { private String name; private List rentals = new LinkedList(); Customer - name - rentals getname() addrental(r) makeinvoice() public Customer (String name) { this.name = name; public String getname () { return name; public void addrental (Rental r) { rentals.add(r); public String makeinvoice () { // liefert einen Rechnungstext über alle ausgeliehenen Filme // hier steckt die gesamte Steuerlogik! UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.4
Customer: makeinvoice() public String makeinvoice () { int price = 0, total = 0, bonus = 0; // Preise in Euro-Cent Iterator films = rental.iterator(); StringBuffer sb = new StringBuffer("Kunde: " + name + "\n"); while (films.hasnext()) { Rental r = (Rental) films.next(); int kind = r.getmovie().getkind(), days = r.getdays(); switch (kind) { case Movie.regular: price = 200; if (days > 2) price += (days - 2) * 150; break; case Movie.newRelease: price = days * 300; break; case Movie.children: price = 150; if (days > 3) price += (days - 3) * 150; break; bonus++; if (kind==movie.newrelease && days>1) bonus++; sb.append("\t" + r.getmovie().gettitle() + "\t"); sb.append(price/100 + "," + price %100 + "\n"); total += price; sb.append("\ngesamtbetrag:\t"+ total/100 + "," + total%100); sb.append("\nbonuspunkte:\t" + bonus); return sb.tostring(); UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.5
Customer: makeinvoice() zerlegen public String makeinvoice () { int price = 0, total = 0, bonus = 0; Iterator films = rental.iterator(); StringBuffer sb = new StringBuffer("Kunde: " + name); while (films.hasnext()) { Rental r = (Rental) films.next(); int kind = r.getmovie().getkind(), days = r.getdays(); switch (kind) { case Movie.regular: computechargefor(rental price = 200; r) if (days > 2) price += (days - 2) * 150; break; case Movie.newRelease: price = days * 300; break; case Movie.children: price = 150; if (days > 3) price += (days - 3) * 150; break; bonus++; if (kind==movie.newrelease && days>1) bonus++; sb.append("\t" + r.getmovie().gettitle() + "\t"); sb.append(price/100 + "," + price %100 + "\n"); total += price; sb.append("\ngesamtbetrag:\t"+ total/100 + "," + total%100); sb.append("\nbonuspunkte:\t" + bonus); return sb.tostring(); UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.6 computebonusfor (Rental r)
Customer: compute Charge/Bonus For (r) public int computechargefor (Rental r) { int price = 0; int kind = r.getmovie().getkind(), days = r.getdays(); switch (kind) { case Movie.regular: price = 200; if (days > 2) price += (days - 2) * 150; break; case Movie.newRelease: price = days * 300; break; case Movie.children: price = 150; if (days > 3) price += (days - 3) * 150; break; return price; public int computebonusfor (Rental r) { return (r.getmovie().getkind() == Movie.newRelease && r.getdays() > 1)? 1 : 2; UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.7
Customer: makeinvoice() NEU public String makeinvoice () { int price = 0, total = 0, bonus = 0; // Preise in Euro-Cent Iterator films = rental.iterator(); StringBuffer sb = new StringBuffer("Kunde: " + name); while (films.hasnext()) { Rental r = (Rental) films.next(); price = computechargefor(r); bonus += computebonusfor(r); sb.append("\t" + r.getmovie().gettitle() + "\t"); sb.append(price/100 + "," + price %100 + "\n"); total += price; sb.append("\ngesamtbetrag:\t"+ total/100 + "," + total%100); sb.append("\nbonuspunkte:\t" + bonus); return sb.tostring(); computecharge/bonusfor beziehen sich auf Rental nicht auf Customer ==> Methoden in die Klasse Rental verschieben UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.8
Rental: getcharge / getbonus () public int getcharge () { int price = 0; int kind = movie.getkind(); switch (kind) { case Movie.regular: price = 200; if (days > 2) price += (days - 2) * 150; break; case Movie.newRelease: price = days * 300; break; case Movie.children: price = 150; if (days > 3) price += (days - 3) * 150; break; return price; public int getbonus () { return (movie.getkind()==movie.newrelease && days>1)? 1 : 2; Customer: public String makeinvoice () {... price = r.getcharge(); bonus += r.getbonus();... UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.9
Movie: getcharge / getbonus (days) public int getcharge (int days) { int price = 0; switch (kind) { case regular: price = 200; if (days > 2) price += (days - 2) * 150; break; case newrelease: price = days * 300; break; case children: price = 150; if (days > 3) price += (days - 3) * 150; break; return price; public int getbonus (int days) { return (kind == newrelease && days > 1)? 1 : 2; Rental: public int getcharge() { return movie.getcharge(days); public int getbonus () { return movie.getbonus(days); UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.10
Price - Klassen abstract class Price { public abstract int getcharge (int days); public int getbonus (int days) { return 1; class RegularPrice extends Price { public int getcharge (int days) { if (days > 2) return 200 + (days-2)*150; else return 200; class NewPrice extends Price { public int getcharge (int days) { return days * 300; public int getbonus (int days) { if (days > 1) return 2; else return 1; class ChildPrice extends Price { public int getcharge (int days) { if (days > 3) return 150 + (days-3)*150; else return 150; UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.11
class Movie { private String title; private Price price; Implementierung von Movie public Movie (String title, Price price) { this.title = title; this.price = price; public String gettitle () { return title; public void setprice (Price p) { price = p; public Price getprice () { return price; public int getcharge (int days) { return price.getcharge(days); public int getbonus (int days) { return price.getbonus(days); UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.12
class Rental { private Movie movie; private int days; Implementierung von Rental public Rental (Movie movie, int days) { this.movie = movie; this.days = days; public Movie getmovie () { return movie; public int getdays () { return days; public int getcharge () { return movie.getcharge(days); public int getbonus () { return movie.getbonus(days); UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.13
Implementierung von Customer class Customer { private String name; private List rentals = new LinkedList(); public Customer (String name) { this.name = name; public void addrental (Rental r) { rentals.add(r); public String makeinvoice () { int price = 0, total = 0, bonus = 0; Iterator films = rentals.iterator(); StringBuffer sb = new StringBuffer("Kunde: " + name + "\n"); while (films.hasnext()) { Rental r = (Rental) films.next(); price = r.getcharge(); bonus += r.getbonus(); sb.append("\t" + r.getmovie().gettitle() + "\t"); sb.append(price/100 + "," + price %100 + "\n"); total += price; sb.append("\ngesamtbetrag:\t"+ total/100 + "," + total%100); sb.append("\nbonuspunkte:\t" + bonus); return sb.tostring(); UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.14
Videothek-Applikation (1) class VideoApp { public static final Price regular = new RegularPrice(); public static final Price newrelease = new NewPrice(); public static final Price children = new ChildPrice(); private Map customers = new HashMap(); private Map movies = new HashMap(); void addmovie (Movie movie) { movies.put(movie.getname(), movie); void addcustomer (Customer customer) { customers.put(customer.getname(), customer); public static void main (String[] args) {... UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.15
class VideoApp {... Videothek-Applikation (2) public static void main (String[] args) { VideoApp bb = new VideoApp(); // bb Blockbuster Customer mg = new Customer("Max Glotzmann"); bb.addcustomer(mg); Movie m1 = new Movie("Star Trek", regular), m2 = new Movie("Terminator VII", newrelease); m3 = new Movie("König der Löwen", children); bb.addmovie(m1); bb.addmovie(m2); bb.addmovie(m3); mg.addrental(new Rental(m1, 3)); mg.addrental(new Rental(m2, 2)); mg.addrental(new Rental(m3, 4)); System.out.println(mg.makeInvoice()); UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.16