Czy klasa jest napisana poprawnie?

0

Witam, mam następujący kod:

    interface IKonstrukcja
    {
        int ZmienWielkosc();
        int ZmienSzerokosc();
        void ZmienPolozenie_Y();
        void KonstruujPrzeszkode();
    }

    interface IPrzeszkodaPierwsza
    {
        void LecPoziomo();
    }

    interface IPrzeszkodaDruga
    {
        void LecDol();
        void LecGora();
    }

    interface ISprawdzaj
    {
        void SprawdzajPrzeszkode();
    }


    abstract public class Przeszkody : IKonstrukcja
    {
        
        protected int predkosc = 60;

        protected Rectangle nowa_przeszkoda;
        protected int wielkosc;
        protected int szerokosc;
        protected int pozycja_Y;

        protected int punkty;
        
        protected int a = -400;
        protected Random rld = new Random();

        public Przeszkody(int predkosc, Rectangle nowa_przeszkoda, int wielkosc, int szerokosc, int pozycja_Y)
        {
            this.predkosc = predkosc;
            this.nowa_przeszkoda = nowa_przeszkoda;
            this.wielkosc = wielkosc;
            this.szerokosc = szerokosc;
            this.pozycja_Y = pozycja_Y;
        }

        protected virtual void SprawdzPredkosc()
        {
            if (punkty < 2)
            {
                predkosc = 60;
            }

            if (punkty == 2)
            {
                predkosc = 40;
            }

            if (punkty == 10)
            {
                predkosc = 35;
            }

            if (punkty == 15)
            {
                predkosc = 30;
            }

            if (punkty == 20)
            {
                predkosc = 25;
            }

            if (punkty == 25)
            {
                predkosc = 20;
            }

            if (punkty == 30)
            {
                predkosc = 15;
            }

            if (punkty == 35)
            {
                predkosc = 10;
            }

            if (punkty == 40)
            {
                predkosc = 5;
            }

            if (punkty == 50)
            {
                predkosc = 1;
            }
        }
        public virtual int ZmienWielkosc()
        {
            return rld.Next(50, 120);
        }
        public virtual int ZmienSzerokosc()
        {
            return rld.Next(80, 200);
        }
        protected virtual int ZmienPunkty()
        {
            return punkty = punkty + 1;
        }
        public virtual void KonstruujPrzeszkode()
        {
            nowa_przeszkoda.Width = ZmienSzerokosc();
            nowa_przeszkoda.Height = ZmienWielkosc();
        }
        public virtual void ZmienPolozenie_Y()
        {
            pozycja_Y = rld.Next(10, 700);
        }
        public virtual void PrzeszkodaOdnow()
        {
            a = rld.Next(-700, -150);
            ZmienPolozenie_Y();
            ZmienPunkty();
            SprawdzPredkosc();
            nowa_przeszkoda.Margin = new Thickness(nowa_przeszkoda.Margin.Left + 2000, pozycja_Y, 0, 0);
        }
    }

    public class TypPierwszy : Przeszkody, IPrzeszkodaPierwsza, ISprawdzaj
    {
        public int Predkosc
        {
            get
            {
                return predkosc;
            }

            set
            {
                predkosc = value;
            }
        }
        public Rectangle Nowa_Przeszkoda
        {
            get
            {
                return nowa_przeszkoda;
            }

            set
            {
                nowa_przeszkoda = value;
            }
        }
        public int Wielkosc
        {
            get
            {
                return wielkosc;
            }

            set
            {
                wielkosc = value;
            }
        }
        public int Szerokosc
        {
            get
            {
                return szerokosc;
            }

            set
            {
                szerokosc = value;
            }
        }
        public int Pozycja_Y
        {
            get
            {
                return pozycja_Y;
            }

            set
            {
                pozycja_Y = value;
            }
        }
        public int Punkty
        {
            get
            {
                return punkty;
            }

            set
            {
                punkty = value;
            }
        }

        

        public TypPierwszy(int predkosc, Rectangle nowa_przeszkoda, int wielkosc, int szerokosc, int pozycja_Y)
            : base(predkosc, nowa_przeszkoda, wielkosc, szerokosc, pozycja_Y)
        {

        }

        public void LecPoziomo()
        {
            nowa_przeszkoda.Margin = new Thickness(nowa_przeszkoda.Margin.Left - 10, nowa_przeszkoda.Margin.Top, 0, 0);
        }

        public void SprawdzajPrzeszkode()
        {
            if (nowa_przeszkoda.Margin.Left > a)
            {
                LecPoziomo();
            }
            else
            {
                KonstruujPrzeszkode();
                PrzeszkodaOdnow();
            }  
        }
    }

    public class TypDrugi : Przeszkody, IPrzeszkodaDruga, ISprawdzaj
    {
        public int Predkosc
        {
            get
            {
                return predkosc;
            }

            set
            {
                predkosc = value;
            }
        }
        public Rectangle Nowa_Przeszkoda
        {
            get
            {
                return nowa_przeszkoda;
            }

            set
            {
                nowa_przeszkoda = value;
            }
        }
        public int Wielkosc
        {
            get
            {
                return wielkosc;
            }

            set
            {
                wielkosc = value;
            }
        }
        public int Szerokosc
        {
            get
            {
                return szerokosc;
            }

            set
            {
                szerokosc = value;
            }
        }
        public int Pozycja_Y
        {
            get
            {
                return pozycja_Y;
            }

            set
            {
                pozycja_Y = value;
            }
        }
        public int Punkty
        {
            get
            {
                return punkty;
            }

            set
            {
                punkty = value;
            }
        }
        private bool gora = false;
        private bool dol =true;

        public TypDrugi(int predkosc, Rectangle nowa_przeszkoda, int wielkosc, int szerokosc, int pozycja_Y)
            : base(predkosc, nowa_przeszkoda, wielkosc, szerokosc, pozycja_Y)
        {

        }

        public void LecDol()
        {
            nowa_przeszkoda.Margin = new Thickness(nowa_przeszkoda.Margin.Left - 10, nowa_przeszkoda.Margin.Top + 10, 0, 0);
        }
        public void LecGora()
        {
            nowa_przeszkoda.Margin = new Thickness(nowa_przeszkoda.Margin.Left - 10, nowa_przeszkoda.Margin.Top - 10, 0, 0);
        }
        public void SprawdzajPrzeszkode()
        {
            if (nowa_przeszkoda.Margin.Left > a)
            {
                if ((nowa_przeszkoda.Margin.Top > 0) && (gora == true))
                {
                    LecGora();
                }
                else
                {
                    gora = false;
                    dol = true;
                }

                if ((nowa_przeszkoda.Margin.Top < 760 - nowa_przeszkoda.Height) && (dol == true))
                {
                    LecDol();
                }
                else
                {
                    dol = false;
                    gora = true;
                }
            }
            else
            {
                KonstruujPrzeszkode();
                PrzeszkodaOdnow();
            }
        }
    }

Chciałbym się dowiedzieć następujących rzeczy:

  • Czy pisanie Interfejsów do tego typu klasy ma jakiś sens, czy lepiej użyć metod chronionych/prywatnych?
  • Czy kod klas jest napisany poprawnie? Co mógłbym dodać, zmienić by zbliżyć się do kodu idealnego?

Przeznaczenie klasy:
Klasa kontroluje obiekt "Rectangle", a mianowicie jego trajektorię lotu, kształt, oraz położenie w oknie aplikacji WPF.

1
  1. większość (wszystkie) właściwości powinny być w klasie przeszkody bo tak to masz copy-pastle
  2. SprawdzPredkosc mi się nie podoba - jeśli już to powinno być if - elseif
  3. co mają interfejsy do metod prywatnych/chronionych? Ich przeznaczenie jest inne

Generalnie wspólny (taki sam) kod powinien być wydzielany do klasy bazowej

0

Czyli jeśli dobrze rozumiem interfejsy które utworzyłem nie mają najmniejszego sensu skoro klasy dziedziczą po sobie?

3

interfejsy służą trochę do czegoś innego - po pierwsze klasa może dziedziczyć po wielu interfejsach ale tylko po jednej klasie bazowej. Po drugie jeśli jakaś klasa dziedziczy po interfejsie to znaczy, że implementuje WSZYSTKIE elementy interfejsu. Interfejsy są głównie stosowane tam, gdzie chcemy wymusić (trochę niefortunne stwierdzenie ale wyjaśni się za chwilę), że klasa x (nawet nieznana na etapie pisania interfejsu) implementuje konkretne metody/posiada konkretne właściwości. Bardzo dobrym przykładem jest interfejs IComparable. Jeśli np. chcesz posortować elementy ArrayList to muszą one implementować interfejs IComparable (to jest to właśnie wymuszenie chcesz użyć metody to zaimplementuj interfejs). Interfejs ten posiada jedną metodę CompareTo która (w skrócie) porównuje dwa elementy ze sobą. Interfejs dla samego interfejsu jest bez sensu. Stosowanie interfejsów powinno wynikać ze stosowanych wzorców projektowych albo wynikać z logiki projektu

4

Miałbyś 10 razy mniej kodu, gdybyś nie pisał w C# sprzed 10 lat i zamiast:

public int Szerokosc
        {
            get
            {
                return szerokosc;
            }
 
            set
            {
                szerokosc = value;
            }
        }

miał:

 public int Szerokosc { get; set; }

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