Czy takie podejście jest dobre?

0

witam, piszę małą aplikacje do zarządzania klientami w supermarkecie. chciałbym się dowiedzieć, czy to podejście, które stosuje jest w miarę zgodne z zasadami, wzorcami panującymi w OOP.

    public interface IProdukt
    {
        decimal Cena
        {
            get;
        }
    }
    public class ProduktSpozywczy : IProdukt
    {
        public string Nazwa {get; set;}
        public decimal Cena {get; set;}
    }

    public class ArtykulChemiczny : IProdukt
    {
        public string Nazwa {get; set;}
        public decimal Cena {get; set;}
    }
    public class Klient
    {
        public int IdKlienta { get; set; }
        public Koszyk koszyk;

        public Klient (int id)
        {
            IdKlienta = id;
            koszyk = new Koszyk();
        }
    }

    public class Koszyk
    {
        public Koszyk()
        {
            stos = new Stack<IProdukt>();
        }
        private Stack<IProdukt> _stos;

        private decimal _doZaplaty;
        public decimal DoZaplaty {
            get { return _doZaplaty; }
            set {_doZaplaty = value; } 
        }

        public Stack<IProdukt> stos
        {
            get { return _stos;}
            set { _stos = value; }
        }

        public void DodajProdukt(IProdukt p)
        {
            DoZaplaty += p.Cena;
            stos.Push(p);
            Console.WriteLine("Produkt dodany do koszyka");
            Console.WriteLine("Aktuanie do zaplaty: " + DoZaplaty);
        }

        public void WyjmijProdukt()
        {
            var x = stos.Pop();
            DoZaplaty -= x.Cena;
            Console.WriteLine("Produkt wyjety z koszyka");
            Console.WriteLine("Aktualnie do zaplaty: " + DoZaplaty);
        }

    }
    public class Program
    {
        static void Main(string[] args)
        {
            ProduktSpozywczy p = new ProduktSpozywczy { Cena = 100, Nazwa = "Bułka" };
            ArtykulChemiczny a = new ArtykulChemiczny { Cena = 50, Nazwa = "Proszek do prania" };
            Klient k = new Klient(1);
            k.koszyk.DodajProdukt(p);
            k.koszyk.DodajProdukt(a);
            k.koszyk.WyjmijProdukt();

            Console.ReadKey();
        }
    } 

W programie chodzi o to, że klient wchodząc do sklepu od razu bierze koszyk. I tutaj moje pytanie, czy dobrze to zrobiłem tworząc pole koszyk w klasie Klient i inicjując ten koszyk w konstruktorze klasy. Oraz czy takie odwoływanie się do koszyka przez klienta jak jest w głównym programie jest poprawne.
Dziękuje za odpowiedź

0

Moim zdaniem nie ma się tu za bardzo czego przyczepić ale sam jestem jeszcze newbie więc niech ktoś inny to potwierdzi. Jedyne co to nazwy po angielsku Client client = new Client() itp i wystarczy samo DoZapłaty {get;set;} jeśli nic tam nie walidujesz.

1

Przede wszystkim nie ma sensu istnienie klas ProduktSpozywczy i ArytkulChemiczny, skoro niczym się od siebie nie różnią, co za tym idzie interfejs IProdukt także nie ma sensu.

To:

 private Stack<IProdukt> _stos;
 
        private decimal _doZaplaty;
        public decimal DoZaplaty {
            get { return _doZaplaty; }
            set {_doZaplaty = value; } 
        }
 
        public Stack<IProdukt> stos
        {
            get { return _stos;}
            set { _stos = value; }
        }

Można zapisać po prostu tak:

public decimal DoZaplaty { get; private set; }
 public Stack<IProdukt> Stos { get; private set; }

Dlaczego takie pole: public Stack<IProdukt> nazwałeś stos? To tak, jakbyś Ty miał na imię "Człowiek". Nazwy zmiennych/pól mają mówić do czego służą, a nie czym są.

I dlaczego w ogóle użyłeś stosu? Czy nie można wyjąć z koszyka innego produktu niż ostatnio włożony?

Metody DodajProdukt i WyjmijProdukt nie powinny niczego wypisywać na ekranie. Ich nazwy sugerują, że one operują na koszyku, nie na konsoli.

0

Może zamiast tworzyć x klas typu ArtykułChemiczny ProduktSpożywczy mogłaby być jedna klasa np. Towar z nazwą, ceną i np. polem kategoria. Poza tym zamiast tworzyć koszyk w kliencie poczytaj o IoC Odwrócenie sterowania , wstrzykiwaniu. Czasem w sklepie braknie koszyków albo rodzina bierze jeden koszyk.

0
somekind napisał(a):

Przede wszystkim nie ma sensu istnienie klas ProduktSpozywczy i ArytkulChemiczny, skoro niczym się od siebie nie różnią, co za tym idzie interfejs IProdukt także nie ma sensu.

Tych klas nie zdążyłem rozbudować jeszcze, także mój błąd przy pisaniu tematu. Będą od siebie się różnić.

somekind napisał(a):

To:

 private Stack<IProdukt> _stos;
 
        private decimal _doZaplaty;
        public decimal DoZaplaty {
            get { return _doZaplaty; }
            set {_doZaplaty = value; } 
        }
 
        public Stack<IProdukt> stos
        {
            get { return _stos;}
            set { _stos = value; }
        }

Można zapisać po prostu tak:

public decimal DoZaplaty { get; private set; }
 public Stack<IProdukt> Stos { get; private set; }

Tylko dlatego, że w getach i setach nie ma większej logiki?

somekind napisał(a):

Dlaczego takie pole: public Stack<IProdukt> nazwałeś stos? To tak, jakbyś Ty miał na imię "Człowiek". Nazwy zmiennych/pól mają mówić do czego służą, a nie czym są.

Jakoś się tak wzorowałem na przykładzie użycia stosu. Nazwę, go kosz.

somekind napisał(a):

I dlaczego w ogóle użyłeś stosu? Czy nie można wyjąć z koszyka innego produktu niż ostatnio włożony?

W treści zadania było napisane, że funkcjonalność koszyka ma być realizowana za pomocą stosu lub kolejki. Abstrahujemy tutaj od rzeczywistej logiki zakupów.

somekind napisał(a):

Metody DodajProdukt i WyjmijProdukt nie powinny niczego wypisywać na ekranie. Ich nazwy sugerują, że one operują na koszyku, nie na konsoli.

Czyli mam stworzyć metody wypisujące komunikat i je wywołać w metodach "DodajProdukt" i "WyjmijProdukt", czy może takie komunikaty wypisywać w Main?

0
karolinaa napisał(a):

Może zamiast tworzyć x klas typu ArtykułChemiczny ProduktSpożywczy mogłaby być jedna klasa np. Towar z nazwą, ceną i np. polem kategoria. Poza tym zamiast tworzyć koszyk w kliencie poczytaj o IoC Odwrócenie sterowania , wstrzykiwaniu. Czasem w sklepie braknie koszyków albo rodzina bierze jeden koszyk.

Co do klas tu już napisałem wyżej. ;)
Ale własnie o takie urozmaicenia mi chodziło jak IoC. Dziękuje ;)

0
newbiq napisał(a):

Tylko dlatego, że w getach i setach nie ma większej logiki?

Tak.

Jakoś się tak wzorowałem na przykładzie użycia stosu. Nazwę, go kosz.

"Kosz"? Taki na śmieci? Już więcej by mówiła nazwa produkty.

W treści zadania było napisane, że funkcjonalność koszyka ma być realizowana za pomocą stosu lub kolejki. Abstrahujemy tutaj od rzeczywistej logiki zakupów.

No ok, chociaż to kompletnie bez sensu.

Czyli mam stworzyć metody wypisujące komunikat i je wywołać w metodach "DodajProdukt" i "WyjmijProdukt", czy może takie komunikaty wypisywać w Main?

Wypisuj w Main, albo w funkcjach pomocniczych w klasie Main. Koszyk to logika biznesowa, nie logika prezentacji, tam powinny być wyłącznie operacje na danych, nie komunikacja z użytkownikiem.

0

A co do IoC

     public class Klient
    {
        public int IdKlienta { get; set; }
        public Koszyk koszyk;

        public Klient (int id, Koszyk k)
        {
            IdKlienta = id;
            koszyk = k;
        }
    }
    Klient k = new Klient(1, new Koszyk());

może być?

0
Klient k = new Klient(1, new Koszyk());
k.IdKlienta = -666;
k.koszyk = null;
k.koszyk.DodajProdukt(new ProduktSpozywczy { Cena = 100, Nazwa = "Bułka" });

Uruchom to i sam powiedz, czy jest ok. ;)

0

masz na myśli, to żeby IdKlienta i koszyk były polami prywatnymi? :)

a dokładnie to ustawienie set na private.

0
newbiq napisał(a):

masz na myśli, to żeby IdKlienta i koszyk były polami prywatnymi? :)

Jak najbardziej, nie powinno się móc zmienić tych wartości z zewnątrz.

0

Ok dzięki za wszystkie informacje i porady.
Ale jeszcze na koniec zapytam o inne rady, jakieś linki czy ćwiczenia na ogólne zasady obiektowości. Zwykle piszę jakiś kod i on działa, ale jednak nawet jak jest zrobiony w miarę poprawnie, to zawsze go można ulepszyć poprzez jakąś praktykę czy wzorzec. Chyba, że po prostu zapoznać się ze wszystkim wzorcami projektowymi i to wystarczy?

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