Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Expand
titleDel 3 – Fleksibel beregning av pris (15%)

Koden for beregning av pris er til nå hardkodet i BikeRental-klassen. Dette er noe det kan være greit å kunne endre på, f.eks. hvis en introduserer abonnement, eller man kan introdusere ulike typer fremkomstmidler med hver sin pris. Koden bør dermed gjøres mer fleksibel. Teknikken du skal bruke er delegering.


Oppgave 3a)

Forklar med tekst og/eller kode hvordan du kan bruke delegering for å gjøre det enklere å bytte ut strategien (beregningslogikken) for prising (globalt). Få med hvordan prisberegningslogikken fra tidligere blir en del av den nye løsningen. 

Hvis du ikke har fått til del 2 kan du bygge på løsningen fra del 1.

Expand
titleLF

I del 2 ble utregning av kostnad ‘hardkodet’ inn i rentBike. Hvis man skal støtte utregning av kostneder ved hjelp av delegering, så må man lage et grensesnitt (interface) som inneholder denne en metode som beregner nettopp kostnadene. I LF har vi laget grensesnittet PricePolicy, som blir implementert av klassen DefaultPricePolicy. I del 2 ble all beregning gjort i en egen hjelpemetode, computePrice. Det er derfor helt greit at grensesnittet inneholder nettopp denne metoden. I BikeRental må en se opprette et DefaultPricePolicy-objekt, og kalle dennes computePrice for å beregne pris. På denne måten kan en opprette et sett med ulike prisberegningsklasser.

Code Block
languagejava
collapsetrue
    private int computePrice(final Person person, final Bike bike, final LocalDateTime returnTime) {
//    PricePolicy pricePolicy = person.getPricePolicy(); // Gammel
        PricePolicy pricePolicy = new DefaultPricePolicy();
        final int price = pricePolicy.computePrice(person, bike, returnTime);
        return price;
    }



public interface PricePolicy {
    public int computePrice(Person person, Bike bike, LocalDateTime returnTime);
}


public class DefaultPricePolicy implements PricePolicy {

    protected int pricePrRental = 0, pricePrHour = 10, pricePrExtension = 5, pricePrLate = 10;

    protected void setPricePrRental(final int pricePrRental) {
        this.pricePrRental = pricePrRental;
    }

    protected void setPricePrHour(final int pricePrHour) {
        this.pricePrHour = pricePrHour;
    }

    protected void setPricePrExtension(final int pricePrExtension) {
        this.pricePrExtension = pricePrExtension;
    }

    protected void setPricePrLate(final int pricePrLate) {
        this.pricePrLate = pricePrLate;
    }

    @Override
    public int computePrice(final Person person, final Bike bike, final LocalDateTime returnTime) {
        // Implementation similar to before...
    }

    private int computeHours(final LocalDateTime startTime, final LocalDateTime endTime) {
        // Implementation similar to before...
    }
}


Oppgave 3b)

Forklar med tekst og kode hvordan en også kan bruke delegering for å tilby individuell prising (altså pr. Person), f.eks. bonus-ordninger.


Expand
titleLF

I 3a ble det lagt opp til delegering av kostnadsberegning, men dette var ikke knyttet til enkeltpersoner. For å implementere individuell prising kan en heller lage et sett med ulike PricePolicy, (studenter, barn, voksne etc.) og knyttet disse til Person-objektet (med gettere og settere). Når rentBike skal beregne kostnad må en så kalled Person-objektet (som igjen ligger i Bike) sin PricePolicy.

Code Block
languagejava
public class Person {

    // Rest similar to before...

    private PricePolicy pricePolicy;

    public PricePolicy getPricePolicy() {
        return pricePolicy;
    }

    public void setPricePolicy(final PricePolicy pricePolicy) {
        this.pricePolicy = pricePolicy;
    }
}


public class BikeRental {

    // Rest similar to before...

    private PricePolicy pricePolicy;

    private int computePrice(final Person person, final Bike bike, final LocalDateTime returnTime) {
        PricePolicy pricePolicy = person.getPricePolicy();
        if (pricePolicy == null) { // If so, default
            pricePolicy = this.pricePolicy;
        }
        final int price = pricePolicy.computePrice(person, bike, returnTime);
        return price;
    }
}


Oppgave 3c)

En antar at det finnes ulike klasser for ulike typer fremkomstmidler en kan leie. Hver type skal kunne ha sine egne sett med verdier brukt til prising, f.eks. pris pr. time og pris pr. tidsforlengelse.

Forklar med tekst og/eller kode hvordan du kan håndtere dette, og spesielt hvordan arvingsmekanismen kan benyttes.


Expand
titleLF

Nå skal altså systemet støtte ulike typer fremkomstmidler, hver med sine priser per time og slikt. Det naturlige er da å lage en abstrakt klasse Vehicle som inneholder priselementer (pris per time, forsentbot etc) og gettere/settere (som getHourRate, setLocation m.m). Ikke alle av disse trenger å være abstrakte, eksempelvis kan det som har med lokasjon å gjøre være implementert i Vehicle. Alle fremkomstmidler (Bike, Hoverboard og slikt) og må så arve denne klassen. Da kan en hente ut prisen per time for en Bike med Bike.getHourRate(). Der en i BikeRental (som egentlig burde skifte navn til VehicleRental) refererer til Bike må en nå i stedet referere til den abstrakte klassen Vehicle.

Vi har fremdeles muligheten til å la ulike Personer ha individuell prising. Mens vi i oppgave 3b la opp til at PricePolicy var hardkodet med prisverdier kan en nå tenke seg at personrabatt nå gjenspeiler seg som en prosentverdi. En vanlig ting er å gi dem prosentreduksjon (som getHourRateFactor) . Vi kan lage PricePolicy for studenter, barn og voksne. I beregningen av kostnad henter vi de faktiske prisene fra fremkomstmiddelet (getHourRate), ganger det med getHourRateFactor, og ganger igjen med antall påbegynte timer. Tilsvarende kan en gjøre for alle andre verdier.

Vi har foreløpig ikke laget noe kodeeksempel for denne delen, da den kan avvike veldig basert på valgene som er gjort tidligere.


...