Zadania do wykonania

Zadanie - kwiaciarnia samoobsługowa.


Napisać aplikację, która symuluje zakupy w kwiaciarni "smoobsługowej".
W kwiaciarni są kwiaty, kwiaty mają swoje nazwy oraz kolory. Ceny kwiatów znajdują się w cenniku.
Do kwiaciarni przychodzą klienci. Klienci mają imiona oraz dysponują jakimś zasobem pieniędzy. Wybierają kwiaty i umieszczają je na wózku sklepowym. Następnie płacą za zawartość wózka i przepakowują ją do pudełka.
Aplikacja wymaga zdefiniowania kilku klas i umiejętnego ich użycia, w taki sposób by następujący program działał poprawnie.

// Klasa "kwiaciarnia"
class Florist {

  public Florist() {
    // Ustalenie cennika
    PriceList pl = PriceList.getInstance();
    pl.set("róża", 10);
    pl.set("bez", 12);
    pl.set("piwonia", 8);
  }

}

// Klasa testująca
class FloristsTest {

  // tu definicja metody valueOf(Box pudelko, String kolor) zwracającej
  // sumaryczną wartość kwiatów o podanym kolorzez, znajdujących się w pudełku

  public static void main(String[] args) {

    // Kwiaciarnia samoobsługowa
    Florist kwiaciarnia = new Florist();

    // Przychodzi klient janek. Ma 200 zł
    Customer janek = new Customer("Janek", 200);

    // Bierze różne kwiaty: 5 róż, 5 piwonii, 3 frezje, 3 bzy
    janek.get(new Rose(5));
    janek.get(new Peony(5));
    janek.get(new Freesia(3));
    janek.get(new Lilac(3));

    // Pewnie je umieścił na wózku sklepowyem
    // Zobaczmy co tam ma
    ShoppingCart wozekJanka = janek.getShoppingCart();
    System.out.println("Przed płaceniem\n" + wozekJanka);

    // Teraz za to zapłaci...
    janek.pay();

    // Czy przypadkiem przy płaceniu nie okazało się,
    // że w wozku są kwiaty na które nie ustalono jescze cceny?
    // W takim razie zostałyby usunięte z wózka i Janek nie płaciłby za nie

    System.out.println("Po zapłaceniu\n" + janek.getShoppingCart());

    // Ile Jankowi zostało pieniędzy?
    System.out.println("Jankowi zostało : " + janek.getCash() + " zł");

    // Teraz jakos zapakuje kwiaty (może do pudełka)
    Box pudelkoJanka = new Box(janek);
    janek.pack(pudelkoJanka);

    // Co jest teraz w wózku Janka...
    // (nie powinno już nic być)
    System.out.println("Po zapakowaniu do pudełka\n" + janek.getShoppingCart());

    // a co w pudełku:
    System.out.println(pudelkoJanka);

    // Zobaczmy jaka jest wartość czerwonych kwiatów w pudełku Janka
    System.out.println("Czerwone kwiaty w pudełku Janka kosztowały: " +
                        valueOf(pudelkoJanka, "czerwony") );

    // Teraz przychodzi Stefan
    // ma tylko 60 zł
    Customer stefan = new Customer("Stefan", 60);

    // ąle nabrał kwiatów nieco za dużo jak na tę sumę
    stefan.get(new Lilac(3));
    stefan.get(new Rose(5));

    // co ma w wózku
    System.out.println(stefan.getShoppingCart());

    // płaci i pakuje do pudełka
    stefan.pay();
    Box pudelkoStefana = new Box(stefan);
    stefan.pack(pudelkoStefana);

    // co ostatecznie udało mu się kupić
    System.out.println(pudelkoStefana);
    // ... i ile zostało mu pieniędzy
    System.out.println("Stefanowi zostało : " + stefan.getCash() + " zł");
  }
}

Program powinien wyprowadzić następujące wyniki:

Przed płaceniem
Wózek własciciel Janek
róża, kolor: czerwony, ilość 5, cena 10.0
piwonia, kolor: czerwony, ilość 5, cena 8.0
frezja, kolor: żółty, ilość 3, cena -1.0
bez, kolor: biały, ilość 3, cena 12.0
Po zapłaceniu
Wózek własciciel Janek
róża, kolor: czerwony, ilość 5, cena 10.0
piwonia, kolor: czerwony, ilość 5, cena 8.0
bez, kolor: biały, ilość 3, cena 12.0
Jankowi zostało : 74.0 zł
Po zapakowaniu do pudełka
Wózek własciciel Janek -- pusto
Pudełko własciciel Janek
bez, kolor: biały, ilość 3, cena 12.0
piwonia, kolor: czerwony, ilość 5, cena 8.0
róża, kolor: czerwony, ilość 5, cena 10.0
Czerwone kwiaty w pudełku Janka kosztowały: 90.0
Wózek własciciel Stefan
bez, kolor: biały, ilość 3, cena 12.0
róża, kolor: czerwony, ilość 5, cena 10.0
Pudełko własciciel Stefan
róża, kolor: czerwony, ilość 5, cena 10.0
Stefanowi zostało : 10.0 zł

Uwaga: w pokazanym tekście programu  występują odwołania do klas: PriceList, Customer, ShoppingCart, Box, Rose, Lilac, Freesia, Peony . Trzeba je odpowiednio zdefiniować, ale oprócz tego nalezy zdefiniować jeszcze co najmniej dwie ważne klasy (których w programie nie widać) potrzebne do spełnienia wymagań postawionych przed programem.

Trzeba też zdefiniować w klasie FloristsTest metodę valueOf(Box pudelko, String kolor) zwracającą wartość kwiatów o podanym kolorze, znajdujących się w pudełku.

Wymaganie podstawowe:
dodanie do powyższego programu zakupów innych kwiatów (np. orchidei) ma byc bardzo łatwe.

Potrzeba tylko :

Przy dodaniu nowego rodzaju kwiatów nie wolno modyfikować żadnych innych klas programu.

Wymagania dodatkowe:
Ważne uwagi.

I na koniec: nie przejmujemy się tym, że np. róże mogą mieć wiele kolorów. Dla uproszczenia przyjęliśmy, że róże są czerwone itd.


Punktacja:

za spełnienie podstawowego wymagania i uzyskanie pokazanego działania programu - max. 5 punktów,
dodatkowo można uzyskać 4 punkty za dobre kodowanie.

w sumie maksimum 9 punktów.




Pomoc 1 (Hashtable)

Przy ustalaniu cen skorzystać z klasy Hashtable, która umożliwia łatwe odnajdywanie informacji wg kluczy.
Do Hashtable dodajemy za pomocą metody put - pary (klucz, wartość), które są odniesieniami do obiektów typu Object.
Np. jeśli chcemy dodać pod kluczem "Ala" wartość typu double, to musimy z double zrobić obiekt (do czego służy klasa Double):

Hashtable ht = new Hashtable();
double d = 1.7;
String s = "Ala";
ht.put(s, new Double(d));    // dodanie wartości (reprezentowanej przez obiekt Double, który zawiera wartośc double 1.7) pod kluczem s ("Ala")

Z tablicy uzyskujemy wartości (które są odniesieniami do obiektów formalnego typu Object) "po kluczu" za pomocą odwołania get(key) np. aby uzyskać wartość zapisaną uprzednio (w wierszach wyżej) pod kluczem "Ala":

Object o = ht.get(s);  // s wskazuje na "Ala" i jest kluczem
                                  // jeżeli w tablicy nie będzie klucza s ("Ala") to metoda zwraca null

Double val = (Double) o;  // obowiązkowa konwersja, by na uzyskanym obiekcie stosować metody klasy Double

double dv = val.doubleValue();  // uzyskujemy wartość typu double, zapisaną w obiekcie typu Double
 

Pomoc 2 (Vector)

Umieszcanie kwiatów w wózku można oprogramować wykorzystując klasę Vector.
Obiekt klasy Vector to dynamiczna (zmieniająca swoje rozmiary w trakcie wykonania) tablica dowolnych obiektów (typ Object).
Metody:

add(Object o) - dodaje referencję do obiektu o jako nowy element wektora,
Object get(int i) - zwraca referencję do obiektu, która zapisana jest w i-ym lemencie wektora
remove(Object o) - usuwa referencję do obiektu o z wektora
remove(int i) - usuwa i-ty element wektora
int size() - zwraca aktualną liczbę elementów wektora

Pomoc 3 ( singleton)

Singleton - to klasa, którą można wykorzystać do stworzenia (w danym programie) tylko jednego obiektu.
Typowa realizacja: