Zadanie Kwiaciarnia - prośba o pomoc

0

Treść zadania:
Napisać aplikację, która symuluje zakupy w kwiaciarni "samoobsł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.

Klasy Florist i FloristTest:
http://wklej.org/id/1314892/

Taki ma być wynik programu:
http://wklej.org/id/1314894/

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 kilka ważnych 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 :
-zdefiniowac nową klasę np. Orchid, przy czym ma to być jak najbardziej oszczędna definicja (kilka wierszy kodu)

  • dodać odpowiedni kod do powyższego programu (np. pl.set("orchidea", 20); janek.add(new Orchid(1)); )
    Przy dodaniu nowego rodzaju kwiatów nie wolno modyfikować żadnych innych klas programu.

Wymagania dodatkowe:
-należy wykorzystać klasy abstrakcyjne i polimorfizm
-należy zminimalizować kod klas ShoppingCart i Box
-należy zdefiniować klasę PriceList jako singleton (możemy mieć zawsze tylko jeden cennik)

Dodatkowe uwagi.
-W kwiaciarni mogą być kwiaty, których zapomniano dodać do cennika. Wtedy przy płaceniu są one usuwane z naszego wózka.
-Może się okazać, że klient nie dysponuje odpowiednią kwotą pieniędzy aby zapłacić za całą zawartość wózka. Wtedy z wózka usuwane są kwiaty, za które klient nie może zapłacić (ale nie pojedynczo, tylko w kompletach np. po stefan.get(new Lilac(3)) usuwane są te trzy bzy na które Stefan nie ma pieniędzy).
-Warto zwrócić uwagę na odpowiednio zdefiniowanie metody toString() w niektórych klasach.


Moja klasa PriceList:

 public class PriceList {
	
	private static PriceList instance = null;
	private PriceList() {}
	
	public static PriceList getInstance(){
		if (instance == null){
			instance = new PriceList();
		}
		return instance;
	}	
}

Klasy z kwiatami:

abstract class Flower {
	
	private String nazwa = "bez nazwy";
	private double cena;
	
    public Flower(String n, double c) {  nazwa = n;  cena = c; }
    
    abstract String rodzaj(); 
    abstract String kolor();
    abstract double cena();	 
}

class Rose extends Flower {   

    private String rodzaj;
    private double cena;
    
    public Rose(String róża, double cena) {
       super(nazwa);				 
       rodzaj = nazwa;
       super(cena);				 
       cena = cena;
    }
 	public String rodzaj() { return rodzaj; }
    public String kolor() { return "czerwony"; }
    public double cena() { return cena; }
 
}

class Lilac extends Flower {   

    private String rodzaj;
    private double cena;
    
    public Lilac(String bez, double cena) {
       super(nazwa);				 
       rodzaj = nazwa;
       super(cena);				 
       cena = cena;
    }
 	public String rodzaj() { return rodzaj; }
    public String kolor() { return "bialy"; }
    public double cena() { return cena; }
 
}

class Peony extends Flower {   

    private String rodzaj;
    private double cena;
    
    public Peony(String piwonia, double cena) {
       super(nazwa);				 
       rodzaj = nazwa;
       super(cena);				 
       cena = cena;
    }
 	public String rodzaj() { return rodzaj; }
    public String kolor() { return "czerwony"; }
    public double cena() { return cena; }
 
}

class Freesia extends Flower {   

    private String rodzaj;
    private double cena;
    
    public Freesia(String frezja, double cena) {
       super(nazwa);				 
       rodzaj = nazwa;
       super(cena);				 
       cena = cena;
    }
 	public String rodzaj() { return rodzaj; }
    public String kolor() { return "zolty"; }
    public double cena() { return cena; }
 
} 

Proszę o sprawdzenie, czy dobrze wprowadziłam polimorfizm i singleton (stosuje go pierwszy raz).
W uwadze do zadania podano, że dwóch klas, których trzeba użyć nie widać w zadaniu, jedną wniosku jest powyższa klasa abstrakcyjna, którą nazwałam Flower. Jaka jest druga?

I jeśli to co wyżej podałam jest poprawne, to czym powinnam zająć się następnie?
Z góry dziękuję za pomoc i wskazówki.

(to moja drugie zadanie, gdzie stosuję polimorfizm, więc nie jestem pewna czy dobrze zrozumiałam jego zastosowanie. I czy takie jego użycie w tym zadaniu pasuje)

1
private String nazwa = "bez nazwy";

Skoro to jest klasa abstrakcyjna to nie moze posiadac wlasnej instancji. Tworzenie tego stringa jest niepotrzebne.

W kazdej klasie dziedziczacej masz

private String rodzaj;
private double cena;

Jesli te zmienne nie sa unikalne dla klasy to wrzucaj je do klasy wyzej i albo wywoluj jakis setter z klasy wyzej super.setX() lub ustaw te zmienne protected tak aby klasy dziedziczace mogly je zmieniac. Tym bardziej nadpisywanie zmiennej cena w klasach nizej mija sie z celem bo takie pole juz w nich istnieje.

abstract class Flower {
 
    protected String nazwa;
    protected double cena;
    protected String rodzaj;
...

Lepiej nie zwracac "hardcoded" stringow z funkcji. Ladniej to wyglada jesli zrobimy sobie zmienna.

private final static String KOLOR = "bialy";

w klasie. Wtedy wszystkie instancje beda dzielily 1 pole o tej wartosci. Ewentualnie mozna zrobic zmienna protected jak wyzej i ustawiac w konstruktorze.

Konstruktory w klasach nizej. Domyslnie slowko super wywola nam konstruktor klasy wyzej. Tak wiec mozna przekazac mu parametry i on te zmienne ustawi.

class Rose extends Flower {   
 
    public Rose(String rodzajKwiata, double cena) {
        super(rodzajKwiata,cena)
    }
...

Skoro PriceList jest singletonem i zawiera informacje o cenach kwiatow, tak więc cena powinna byc ustawiana automatycznie bez koniecznosci przekazania jej jako parametr. Nie mam teraz za duzo czasu na rozwijanie. Pokombinuj, albo niech ktos inny dopisze. ;)

dodanie znaczników <code class="java"> - furious programming

0

Poprawiłam z polimorfizmem. Z singletonem niestety nie bardzo wiem jak zrobić, to co podałam w kodzie wyżej znalazłam w jednym z wykładów, że tak wygląda singleton po prostu i do czego się go używa. Ale na to zadanie przerobić nie umiem.

I mam pytanie do klas Shopping Cart i Box. Co znaczy, że mają być zminimalizowane? Co powinno się użyć by takie były?

Chcę utworzyć klasę WozekSklepowy (tak mi się wydaje, że to jedna z tych niewidocznych w zadaniu).
Zastanawiam się czy zastosowanie tam LinkedList do kwiatów to dobry pomysł?
I jak w takiej klasie odwoływać się do singletonu?

I metoda:

public valueOf(Box pudelko, String kolor){ 

w klasie FloristsTest też chyba powinna się odwoływać do singletonu. Jak coś takiego zrobić?

0

Znalazłam coś takiego:

 	public valueOf(Box pudelko, String kolor){
		
       int value = 0;
            
            foreach (var flower in box.Flowers){
                if (flower.kolor == kolor)
                    value += flower.cena * PriceList.Instance.Prices[flower.rodzaj];
            }
            return value;
        }		
	}

Nie rozumiem tylko zapisu:

foreach (var flower in box.Flowers)

a tutaj:

 PriceList.Instance.Prices[flower.rodzaj];

jest odwołanie do klasy PriceList z singletonem.
Krycho w poście wyżej napisał by cena w singletonie była ustawiana automatycznie. Mógłby ktoś powiedzieć jak coś takiego zrobić?

1

Krycho w poście wyżej napisał by cena w singletonie była ustawiana automatycznie. Mógłby ktoś powiedzieć jak coś takiego zrobić?

Rzeczywiscie zle to ujalem i moglas zle zrozumiec. Chodzilo mi tu o to ze jesli PriceList zawiera ceny konkretnych typow kwiatow to cena ta powinna byc brana z singletona w klasach typu Flower. Sama zmienna double cena jest wtedy zbedna i mozna zrobic cos w stylu

public double getPrice() { return PriceList.getInstance().priceOf(name); }

Bezposrednio w klasie Flower. Wtedy cena bedzie pobierana z listy cen, tak ze zmiana tej ceny na liscie bedzie skutkowala automatyczna zmiana jej w kazdym obiekcie typu Flower.

Odpowiednik petli foreach w javie to np.

List<String> list = new ArrayList<>();
for(String element : list) {
    // iterowanie po elementach listy
}

Box zawierac bedzie w sobie produkty(tutaj kwiaty) kwiaty zwracaja swoja wartosc. One odwoluja sie do listy cen. Do tego widac ze konstruktor Flower i pochodnych powinien przyjmowac inta wskazujacego ilosc kwiatow jakie ktos bierze(dziwne, bo obiekt powiniene reprezentowac pojedynczy kwiat, no ale coz).

Box i shoppingcart moglyby miec jakas klase wspolna. Chociaz i tak logika w niektorych miejscach jest niezbyt dobra.

Na wiecej nie mam czasu aktualnie ;)

0
Krycho napisał(a):

Rzeczywiscie zle to ujalem i moglas zle zrozumiec. Chodzilo mi tu o to ze jesli PriceList zawiera ceny konkretnych typow kwiatow to cena ta powinna byc brana z singletona w klasach typu Flower. Sama zmienna double cena jest wtedy zbedna i mozna zrobic cos w stylu

public double getPrice() { return PriceList.getInstance().priceOf(name); }

Bezposrednio w klasie Flower. Wtedy cena bedzie pobierana z listy cen, tak ze zmiana tej ceny na liscie bedzie skutkowala automatyczna zmiana jej w kazdym obiekcie typu Flower.

Nie wiem czy dobrze zrozumiałam, chodzi o to by wstawić tą linijkę kodu zamiast private double cena? (czy zamiast abstract double cena();?)
Bo nie wiem czy jeśli ceny będą pobierane z singletona to jest potrzebne abstract double cena().
Chyba dalej nie wiem jak tą klasę Flower przerobić :( bo wtedy taki zapis chyba też odpada:

    private String rodzaj;  private double cena;
	
    public Flower(String n, double c) {  nazwa = n;  cena = c; } 

Dzięki za wyjaśnienie tego z foreach. Spróbuję to jakoś jeszcze przerobić.

Z ShoppingCart to próbuję z ArrayList (właściwie to nie wiem czy lepiej ArrayList czy LinkedList). Może po prostu utworzyć w ShoppingCart jakąś listę kwiatów. Za to w Box jakieś odwołanie do tej listy i klasy Customer? Klasy Customer za to chyba na razie nie mam jak zrobić bez ShoppingCart, chyba, że źle to analizuje.

Próbowałam coś z tym ShoppingCat. Mogłoby być coś takiego?

public class ShoppingCart{
	
        public ShoppingCart(){
            ArrayList<Flower> Flowers = new ArrayList<Flower>();
        }
    }
} 

A klasę Customer zacząć tak:

public class Customer{
	
        public Customer(String i, int p){
            imie = i;
            pieniadze = p;
            ShoppingCart = new ShoppingCart();
        }	
        
        public void Get(Flower flower){	
            ShoppingCart.Flowers.Add(flower);
        }
         

Na razie tylko metoda Get, bo nie wiem czy taki sposób będzie dobry.

0

Mam problem z wprowadzeniem do klasy PriceList metody set, by działało to poprawnie w tym singletonie, szukałam w internecie jakiś przykładów na to, jednak nic podobnego nie znalazłam.

0
 import java.util.ArrayList;

class Florist {

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

class PriceList {
	
	private static PriceList instance;
	private PriceList() {}
	
	public static PriceList getInstance(){
		if (instance == null){
			instance = new PriceList();
		}
		return instance;
	}
	
	public void set(String nazwa, double cena){
		Kwiaty kwiaty = new Kwiaty(nazwa, cena);
	}
	
/*	public int podajCene(){
		return Kwiaty.cena;}
	}*/
	
}
	

class Kwiaty{
	static String nazwa;
	static double cena;
	
	Kwiaty(String nazwa, double cena){
		this.nazwa = nazwa;
		this.cena = cena;
	}
}

abstract class Flower {

    int ilosc; double cena;
    
    Flower(){  }
	
	Flower(int i, double c) {	ilosc = i;   cena = cena; }
	
    abstract String getType(); 
    abstract String getColour();
    int getNumber(){ return ilosc; };
    double getPrice(){ return cena; };
    
    public String toString() {
        return getType() + ", kolor: " + getColour() + ", sztuk: " + getNumber() + ", cena: " + getPrice() + "\n";
    }
    	 
}

class Rose extends Flower { 
    
    public Rose(int ilosc, int cena) {
        super(ilosc, cena);    ilosc = ilosc; cena = cena; }
    
 	String getType() { return "roza"; }
    String getColour() { return "czerwony"; }
    int getNumber() { return ilosc; }
    double getPrice(){ return cena; };
 
}

class Lilac extends Flower { 

    public Lilac(int ilosc, int cena) {
        super(ilosc, cena);     ilosc = ilosc; cena = cena; }
    
 	String getType() { return "bez"; }
    String getColour() { return "bialy"; }
    int getNumber() { return ilosc; }
    double getPrice(){ return cena; };
 
}

class Peony extends Flower {  

    public Peony(int ilosc, int cena) {
        super(ilosc, cena);     ilosc = ilosc; cena = cena; }
    
 	String getType() { return "piwonia"; }
    String getColour() { return "czerwony"; }
    int getNumber() { return ilosc; }
    double getPrice(){ return cena; };
 
}

class Freesia extends Flower { 

    public Freesia(int ilosc, int cena) {
        super(ilosc, cena);       ilosc = ilosc; cena = cena; }
    
 	String getType() { return "frezja"; }
    String getColour() { return "zolty"; }
    int getNumber() { return ilosc; }
    double getPrice(){ return cena; };
 
}

Do tej pory mój kod wygląda tak, po wielu przeróbkach.

Za to dowiedziałam się, że dwie niewidoczne klasy to, jedna abstrakcyjna dla kwiatów (którą mam, ale nie wiem czy poprawie) a druga ma być dla klas ShoppingCart i Box. Tylko jak taką klasę zrobić? I jak wtedy by wyglądały klasy Box i ShoppingCart?

Oraz mam problem z klasą Customer i valueOf.

Pomoże ktoś?

0

Poradziłaś sobie z programem?

1 użytkowników online, w tym zalogowanych: 0, gości: 1