Hint til automat
Metodene i modellklassen
Forslag til metoder i modellklassen Automat (en rekke andre løsninger er mulig):
public boolean leggPå(int mynt) {} public boolean velgProdukt(String p) {} public String valgtProdukt() {} public int sumLagtPå() {} public String statusmelding() {} public int vekslepenger(int) {}
De to første metodene sjekker at mynt/produkt er lovlig (returnerer boolean). Brukergrensesnittet AutomatApp vil fortsette å kalle på disse helt til brukeren velger produkt. Deretter kan AutomatApp hente ut valgt produkt, samlet beløp lagt på, samt en String-metode som leverer opplysninger om status (hvordan gikk bestillingen) og en int-metode som returnerer vekslepenger for en gitt myntenhet. Hvis f.eks. vekslepenger(5) gir 3 betyr dette at brukeren får tilbake 3 5-kroner.
Poenget med metoden statusmelding er at automaten kan gi beskjed om at en bestilling ikke lar seg gjennomføre selv om brukeren legger på lovlige mynter og velger et lovlig produkt: Automaten kan være tom for dette produktet, det er lagt på for lite penger, automaten kan være tom for vekslepenger osv.
Brukergrensesnittet
Klassen AutomatApp bør opprette et objekt av Automat, og deretter starte ei evig løkke som gjør følgende:
- Be brukeren om å legge på mynter og avslutte med å velge produkt.
- I det brukeren velger produkt, skal produkt og vekslepenger "leveres" (i form av en utskrift på skjermen).
- Vent på neste bruker.
Oppgaven legger opp til et tekstlig brukergrensesnitt, der brukeren skriver inn 1, 5, 10 eller 20 for å legge på mynter, og -1 for brus, -2 for kaffe og -3 for sjokolade. Det kan være naturlig å la brukeren avslutte programmet ved å skrive inn f.eks. 0.
Hvis man lager et grafisk brukergrensesnitt vil det være naturlig å håndtere innputt med knapper, og brukeren kan i stedet avslutte programmet ved å lukke vinduet. Man bør lage modellklassen slik at den fungerer med begge typer av brukergrensesnitt.
Start med en nedskalert versjon
Dette er en krevende oppgave, så for å komme i gang er det lurt å starte med en forenklet utgave:
- Begrens automaten til ett eneste produkt, som automaten har et ubegrenset antall av.
- Begrens automaten til å akseptere og levere kun 1-kroner.
Tilstanden i automaten
Automaten (i fullversjon) må lagre følgende opplysninger:
- Prisen på hvert produkt (kaffe, sjokolade og brus).
- Beholdningen av mynter (1kr, 5kr, 10kr og 20kr).
- Beholdningen av produkt.
- Beløpet brukeren har lagt på (øker myntbeholdningen).
- Produktet brukeren har valgt (teller ned produktbeholdningen).
Ta vare på produkt
Automaten må ta vare på prisen til hvert enkelt produkt. En enkel løsning:
private int kaffePris = 5; private int sjololadePris = 8; private int brusPris = 12;
Automaten bør også lagre navnet på hvert produkt og hvor mange som er igjen.
Ulempen med forslaget over er at koden blir bundet tett opp til akkurat disse tre produktene. En bedre løsning:
private String[] prodNavn = { "Kaffe", "Sjokolade", "Brus" }; private int[] prodPriser = { 5, 8, 12 }; private int[] produkt = { 50, 50, 50 };
En mer objektorientert løsning vil innføre en klasse Produkt:
public class Produkt { private String navn; private int pris; private int antall; // Konstruktør og set/get-metoder }
De tre tabellene over kan dermed representeres på denne måten:
Produkt[] produkt = { new Produkt( "Kaffe", 5, 50 ), new Produkt( "Sjokolade", 8, 50 ), new Produkt( "Brus", 12, 50 ), }
Ta vare på mynter
Det er mulig å velge en helt enkel løsning:
private int ant1kr = 50; private int ant5kr = 50; private int ant10kr = 50; private int ant20kr = 50;
Men igjen vil koden bli svært tett koblet til at vi har nettopp disse fire myntenhetene. En løsning med tabeller:
private int[] myntEnheter = { 1, 5, 10, 12 }; private int[] mynter = { 50, 50, 50, 50 };
Som for produkt kan vi alternativt innføre en ekstra klasse Mynt med objektvariabler enhet og antall.
Ta vare på aktiv bestilling
En grei variant er kun å ta vare på beløpet brukeren har lagt på, sammen med valgt produkt:
private int lagtPå; // Sum lagt på private String valgtProdukt; // Hvilket produkt er valgt
Hvis en bestilling blir avbrutt vil kanskje brukeren ønske å få tilbake nøyaktig de samme myntene som er lagt på, f.eks. 2 5-kroner, og ikke bare det samme beløpet, f.eks. 1 10-krone. Det krever i så fall at vi ikke bare tar vare på beløpet som er lagt på, men antall av hver mynt. Løsningen over legger opp til at man bare legger myntene inn i myntsamlingen.
Vekslepenger
Hvis myntbeholdning er representert ved en heltallstabell myntEnheter som over, er det naturlig å representere vekslepenger på samme måte:
private int[] vekslepenger;
Da vil vekslepenger[0] inneholde antall 1-kroner, vekslepenger[1] antall 5-kroner osv.