Folien
Transcription
Folien
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 • Neuerscheinung • Kindervideo • Gewünschte Ausgabe: 1 Punkt 1 Punkt + 1 Zusatzpunkt, ab 2 Tage 1 Punkt Kunde: Max Glotzmann Star Trek Terminator VII König der Löwen Gesamtpreis Bonuspunkte UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung 3,50 6,00 3,00 12,50 4 A.1 Klasse Movie (Filme) reine Datenklasse Movie class Movie { public static final int regular = 0, newRelease = 1, children = 2; private String title; private int kind; - 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 werden 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) { computeChargeFor(Rental r) 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; } computeBonusFor (Rental r) 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); UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.6 return sb.toString(); } Customer: compute Charge/Bonus For (r) public int computeChargeFor (Rental r) { int price = 0; int kind = r.getMovie().getKind(), days switch (kind) { case Movie.regular: price = 200; if (days > 2) price += (days case Movie.newRelease: price = days * case Movie.children: price = 150; if (days > 3) price += (days } return price; } = r.getDays(); - 2) * 150; break; 300; break; - 3) * 150; break; public int computeBonusFor (Rental r) { return (r.getMovie().getKind() == Movie.newRelease && r.getDays() > 1) ? 2 : 1; } 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) case Movie.newRelease: price = days * 300; case Movie.children: price = 150; if (days > 3) price += (days - 3) } return price; } public int getBonus () { return (movie.getKind()==Movie.newRelease && } Customer: public String makeInvoice () { ... price = r.getCharge(); bonus += r.getBonus(); ... } UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung * 150; break; break; * 150; break; days>1) ? 2 : 1; A.9 Movie: getCharge / getBonus (days) public int getCharge int price = 0; switch (kind) { case regular: if (days > 2) case newRelease: case children: if (days > 3) } return price; } (int days) { price price price price price = 200; += (days - 2) * 150; break; = days * 300; break; = 150; += (days - 3) * 150; break; public int getBonus (int days) { return (kind == newRelease && days > 1) ? 2 : 1; } 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 Implementierung von Movie class Movie { private String title; private Price price; public Movie (String title, Price price) { this.title = title; this.price = price; } public public public public public String getTitle () { return title; } void setPrice (Price p) { price = p; } Price getPrice () { return price; } int getCharge (int days) { return price.getCharge(days); } int getBonus (int days) { return price.getBonus(days); } } UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.12 Implementierung von Rental class Rental { private Movie movie; private int days; public Rental (Movie movie, int days) { this.movie = movie; this.days = days; } public public public public Movie getMovie () { return movie; } int getDays () { return days; } int getCharge () { return movie.getCharge(days); } 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); } ... UE zu SW 2 Fallstudie OO-Entwurf: Videothek-Verwaltung A.15 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