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:

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:

Tilstanden i automaten

Automaten (i fullversjon) må lagre følgende opplysninger:

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.