Wątek przeniesiony 2020-10-19 21:14 z Algorytmy i struktury danych przez somekind.

Jak tworzyć dobre klasy? (na przykładzie gry Snake)

0

Cześć,

w innym temacie oddałem do oceny mój pierwszy projekt w Pythonie - grę w Snake'a: Snake - mój pierwszy projekt w Pythonie

Gdyby ktoś nie chciał czytać tematu z moim Wężem, podaję bezpośredni link do repozytorium: https://github.com/bearek/snake

Mimo moich wielu lat doświadczenia programistycznego, nadal nie mam wyczucia w projektowaniu klas. Nigdy nie wiem ile zależności lub elastyczności to zbyt dużo.

Gra w Snake'a to idealny przykład na trening tworzenia klas. Aktualnie moja gra nie ma klasy reprezentującej samą postać węża. Chciałbym taką napisać, żeby odseparować elegancko węża od reszty kodu. Ale nie wiem co wąż "powinien", a czego "nie powinien". Mam na myśli przede wszystkim relację wąż-plansza. Planszę mam zaprogramowaną jako siatkę o wymiarach X×Y (a jakże). Mam kilka pomysłów na to, jak określić tę relację:

  1. Brak informacji o siatce w klasie Węża. Wąż byłby zaprogramowany jako lista kierunków, bez informacji o położeniu na siatce. Jakby nie patrzeć, to oddaje naturę węża - wąż się wije w określonych kierunkach i tyle.
  2. Informacja o szerokości i wysokości siatki, by móc przechowywać punkty węża w klasie Snake. Wtedy wąż mógłby wiedzieć np. żeby się zawinąć po przejściu krawędzi ekranu, a także wiedziałby, kiedy gryzie sam siebie. W przypadku pomysłu 1. również wykryłbym pętlę, w której wąż sam się dziabnął, ale już np. śmierci w wyniku zbyt długiego węża, który po zawinięciu się doszedł aż do własnego ogona - nie.
  3. Użycia planszy jako dependency i na tej podstawie obliczanie logiki węża.

Nie mam wyczucia które rozwiązanie jest uznawane za "najczystsze" i czy w ogóle któreś.

Czy jest jakiś zestaw pytań, które mogę sobie zadać, by jak najlepiej zaprojektować klasy? Czy może te trzy powyższe rozwiązania są równie dobre? Chciałbym wyrobić w sobie intuicję projektowania klas. Z góry dzięki za podpowiedzi :)

0

Podoba mi się że napisałeś snake'a w pythonie.
Najlepiej tak tworzyć klasę żeby się łatwo programowało - ile zależności lub elastyczności jest potrzebne a ile to zbyt dużo to trudne pytanie. Wszystko zależy od przyszłych wymagań, zazwyczaj elastyczność przydałaby się tam gdzie jej nie ma a jest niepotrzebna tam gdzie jest. Jeśli samemu ma się jakąś wizję na rozwój projektu to można coś tam przewidzieć ale jeśli wymagania przychodzą z zewnątrz i nie możemy się ich spodziewać to naprawdę ciężko się przyszykować.
Snake to akurat tak prosta gierka że w ogóle nie ma co w niej projektować - zaimplementować w najprostszy sposób i tyle. W zasadzie kod będzie prawdopodobnie najczytelniejszy gdy w projekcie będzie tylko jedna lub dwie klasy...

Brak informacji o siatce w klasie Węża. Wąż byłby zaprogramowany jako lista kierunków, bez informacji o położeniu na siatce. Jakby nie patrzeć, to oddaje naturę węża - wąż się wije w określonych kierunkach i tyle.

z jednej strony tak, z drugiej ciężko przełożyć klasy na realne życie 1:1. W naturze wąż mniej więcej ma pojęcie gdzie się znajduje, nie zna swoich współrzędnych ale też nikt tak naprawdę ich nie zna dopóki ich nie zmierzy i zaobserwuje. No i współrzędnych względem czego? Nie ma obiektu w rzeczywistym świecie który przetrzymuje współrzędne wszystkich innych obiektów, na pewno nie przetrzymuje ich ziemia (jako plansza).

Moim zdaniem jednak lepiej i dużo prościej gdyby obiekty znały jednak swoje położenie, dla elastyczności lepiej gdy obiekty znają względne a nie absolutne położenie względem obiektu na którym się znajdują (w ten sposób łatwo węża przenieść na platformę a platformę przenosić niezależnie i jeszcze nią obracać).
Polecam spróbowanie TDD - klasy w tym podejściu się projektują w zasadzie same i powstaje czyste, intuicyjne API https://www.infoq.com/articles/test-driven-design-java/

0

Co do ogólnych zasad projektowania klas w paradygmacie OOP to poczytaj sobie o czymś takim jak SOLID.
Dodatkowo pamiętaj, że klasa ma zawierać tylko same potrzebne rzeczy.

1
Czitels napisał(a):

Dodatkowo pamiętaj, że klasa ma zawierać tylko same potrzebne rzeczy.

Powiedziałbym to samo, ale inaczej: klasa ma wyrazisty zakres odpowiedzialności, tzn nie jest zbieraniną "wszystko co się trafiło"

0

Niedługo podzielę się odświeżonymi klasami. Idealnie nie jest, będę otwarty na sugestie.

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