Permalänk
Medlem

C# Sodacrate - "refactor"

Hej.

Jag skulle vilja ha lite tips på hur jag kan göra min kod lite mer smidig.
I nuläget har jag klasserna Sodacrate och Beverage.

Sodacrate inehåller själva logiken i programmet, medans Beverage är själva flaskan/drycken.
Jag skulle dock vilja göra det hela lite mer smidigt så att man kan hantera skapande av Beverage lite mer dynamiskt.

Istället för att varje gång passa Namn, Pris och Typ till Beverage, så vill jag egentligen på 1 stället i koden definiera alla typer av dryck, samt dess pris och typ.

Mao vill jag egentligen bara skapa ett objekt av klassen typ så här "blabla = new Beverage("Cola")"
Då skall alltså objektet få sina egenskaper satta enligt var Cola skall motsvara för pris och typ av dryck automatiskt.

Är det vettigt att lägga detta i en grötig IF sats i construktorn för Beverage, eller kan man göra det på lite snyggare sätt?
Lite osäker, men jag vill Inte använda mig av listor, utan endast "vanliga" objekt och vektorer.

class Beverage { private string _name; private int _price; private string _type; public Beverage(string name, int price, string type) { this._name = name; this._price = price; this._type = type; } public string Name{ get { return this._name; } } public int Price { get { return this._price; } } public string Type { get {return this._type; } } }

Som synes så kan man passa vad man vill som namn osv, så ingenting är definierat gällande vilken typ av drycker man kan skapa.

Visa signatur

- none -

Permalänk
Medlem

I am not a programmer, men spontant tycker jag inte man ska skicka in en sträng som ett argument (skicka kanske en enumerator?). Någonstans på vägen känns det ju som att du kommer behöva en switch/ifelse slinga om du gör det dock. En annan grej är ju göra klassen Beverage abstrakt och då istället skapa klasser som Cola som ärver egenskaperna från den. Då innehåller själva klassdefinitionerna dessa värden, och dessa kan ligga samlade under en och samma fil. Då kan du använda dig av polymorphism typ Beverage cola = new Cola();

Permalänk
Medlem

Kolla upp Polymorphism, tror det är exakt det du letar efter

Kort och gott: Du skapar olika klasser för dina drycker, t.ex. Cola, Fanta, Sprite osv. Alla dessa typer är baserat på din huvud-klass "Beverage" som har variablerna, Pris, Namn och Typ definierat.

Cola är en typ av Beverage, vilket innebär att den kommer ärva sin typs egenskaper (läs: variabler, funktioner m.m).

Ett simpelt exempel nedan visar vad jag menar

public class Beverage{ public string Name; public float Price; } public class Cola : Beverage{ // Cola ärver av Beverage public Cola(){ Name = "Cola"; Price = 18.99; } } public class Fanta : Beverage{ public Fanta(){ Name = "Fanta"; Price = 16.49; } } ... // Skapar en lista med dina drycker List<Beverage> drycker = new List<Beverage>{ new Cola(), new Fanta() }

Visa signatur

NZXT H510 Flow MSI B450 Tomahawk MAX
AMD Ryzen 5800X3D RX 7900XTX Kingston Fury 64GB

Permalänk
Medlem

Eftersom du läser programmering 1 (?) så är arv inte något du lärt dig i kursen. Men vill du använda det så blir det säkert ett stort plus i kanten.

Det du annars kan göra är att skapa en konstruktor innehålandes en switch baserad på konstruktorns argument. I switchens cases sätter du attributen för objektet.

Exempel om argumentet är "Cola" så sätter du pris m.m. i detta caset.

Edit: Argumentet kan ju vara ett artikelnummer, tex. -> int art = 92132076; eller liknande.

Visa signatur

There is always a price to pay for convenient

Permalänk
Medlem

Att skapa en klass för varje sorts dryck fungerar ju, men det är ingen vidare bra lösning eftersom du då t.ex. inte kan lägga till nya drycker enkelt utan att lägga till mer kod. Det är heller inte någon särskilt bra idé att stoppa logiken i Beverage-klassen, eftersom det gör klassen onödigt komplicerad och oflexibel.

Vad du nog egentligen är ute efter är en Factory-klass, d.v.s. en klass vars enda syfte är att skapa nya Beverage-objekt. Fördelen med en sån klass är att du kan ha flera olika metoder för att skapa nya Beverage-objekt, t.ex. från en lista av hårdkodade parametrar, från en fil, från en databas, etc, utan att behöva ändra på Beverage-klassen i sig.

Det kan alltså vara något så enkelt som t.ex. (jag kan inte C# utantill, så koden kanske inte är helt korrekt):

class BeverageFactory { static public Beverage fromName(string name) { switch (name) { case "Cola": return Beverage("Cola", 5, "Brun sörja"); break; ... default: // Felhantering break; } } } // Skapa en Cola: Beverage cola = BeverageFactory.fromName("Cola");

Permalänk
Medlem
Skrivet av perost:

Att skapa en klass för varje sorts dryck fungerar ju, men det är ingen vidare bra lösning eftersom du då t.ex. inte kan lägga till nya drycker enkelt utan att lägga till mer kod. Det är heller inte någon särskilt bra idé att stoppa logiken i Beverage-klassen, eftersom det gör klassen onödigt komplicerad och oflexibel.

Vad du nog egentligen är ute efter är en Factory-klass, d.v.s. en klass vars enda syfte är att skapa nya Beverage-objekt. Fördelen med en sån klass är att du kan ha flera olika metoder för att skapa nya Beverage-objekt, t.ex. från en lista av hårdkodade parametrar, från en fil, från en databas, etc, utan att behöva ändra på Beverage-klassen i sig.

Det kan alltså vara något så enkelt som t.ex. (jag kan inte C# utantill, så koden kanske inte är helt korrekt):

class BeverageFactory { static public Beverage fromName(string name) { switch (name) { case "Cola": return Beverage("Cola", 5, "Brun sörja"); break; ... default: // Felhantering break; } } } // Skapa en Cola: Beverage cola = BeverageFactory.fromName("Cola");

Tack för tipset, detta verkar smidigt nog så fick jag samtidigt lära mig något nytt.

class BeverageFactory { static public Beverage FromName(string name) { switch (name) { case "Cola": return new Beverage("Cola", 16, "Läsk"); case "Fanta": return new Beverage("Fanta", 16, "Läsk"); case "Ramlösa": return new Beverage("Ramlösa", 16, "Mineralvatten"); case "Cider": return new Beverage("Cider", 16, "Alkohol"); case "Öl": return new Beverage("Öl", 16, "Alkohol"); default: return null; } } }

Nog för att default case kanske inte blev så snyggt, men så får det vara för nu.

Lite snyggare blev det nu att skapa nya flaskor.

// Add bottle method //public void AddBottle(string n, int p, string t, int i) public void AddBottle(string n, int i) { // bottles[i] = new Beverage(n, p, t); bottles[i] = BeverageFactory.FromName(n); qtyBottles++; }

Visa signatur

- none -