Idealne programowanie obiektowe

Własne projekty oraz implementacje.

Moderator: xxSlayeRxx

Idealne programowanie obiektowe

Sponsor

Sponsor
 

Idealne programowanie obiektowe

Postprzez Mef » Śr lis 07, 2012 10:12 pm

Witam, nie jestem pewien czy ten post powinien znajdować się tutaj czy w dziale Newbie. W kazdym razie mam dość duzy problem z przestawieniem się na programowanie obiektowe. Zdecydowałem się stworzyc kilka 2-minutowych projektow do oceny czy idę w dobra strone. Jesli zalaczony mikroprojekt jest w miare ok to chcialbym abyście czepiali się absolutnie wszystkiego co nie jest zgodne z 'duchem programowania obiektowego'.

Od dluzszego czasu mam problem z miksowaniem GUI z logiką aplikacji w jednej klasie, wspolpracą obiektow i zbytnim 'strukturalizowaniem'. W tym przypadku zawarlem GUI w klasie Form1, nie wiem czy to dobrze. Wiem, ze projekt jest smiesznie mały ale nie ma sensu tworzyc wiekszego jesli już coś robię źle.

Tyle, w zalaczniku jest powalająca kostka do gry - z góry dziękuje za wszelkie uwagi.
Załączniki
KostkaDoGry.zip
(196.94 KiB) Pobrane 370 razy
Mef
New member
 
Posty: 7
Dołączył(a): Śr lis 07, 2012 10:00 pm

Re: Idealne programowanie obiektowe

Postprzez xxSlayeRxx » Śr lis 07, 2012 11:06 pm

public int AktualnieWylosowano { get; set; }
Ja bym dal:
public int AktualnieWylosowano { get; private set; } //ewentualnie protected :D - hermetyzacja
chyba nie chcesz, zeby przyszedl cziter i podmienial Ci wartosci kostki :D

Ja bym zrobil to troche ianczej w konstruktorze zamiast liczba scian dalbym tablica z bitmapami scian.

Nastepnie liczbie scian bym przypisal tablica.count, dzieki temu mozesz zrobic np. 3 rozne kostki, a w kodzie nie musisz sie przejmowac ktory obrazek aktualnie przypisac.

Robisz tylko kostkaBiala.Wylosuj();
picturebox.Image = kostkaBiala.AktualnaSciana();

kostaCzerwona dla gracza drugiego itp (albo np. jesli kostki sa wazniejsze i mniej wazne jak w grach RPG)


albo mozesz zrobic tak public virtual void Wylosuj(picturebox pb)
i tutaj podac to co masz przy kliknieciu przycisku (oczywiscie uwzgledniajac zmiany powyzej z tablica bitmap)

dzieki temu jak ktos bedzie chcial zmienic dzialanie Wylosuj wystarczy ze zrobi override Wylosuj
i np zamiast losowac tak jak Ty podaje od razu wylosowana wartosc - otwarte na rozszerzenie, ale zamknięte na modyfikacje

dobry posunieciem jest virtual przekulnij - juz widze zastosowanie :D jak chcesz np. zeby koledze wypadaly mniejsze wartosci czesciej (np. gra w chinczyka :D) to inaczej mu sie bedzie kulalo a inaczej Tobie :P


-----
A i raczej nie ten dzial :P
xxSlayeRxx
Member
 
Posty: 661
Dołączył(a): Pt lip 08, 2011 10:24 pm

Re: Idealne programowanie obiektowe

Postprzez Mef » Cz lis 08, 2012 3:23 pm

Dzięki za odpowiedz ;)

Calkowicie zgadzam się z "protected set;". Zauwazylem ten dysonansik juz przy pisaniu kodu ale szczerze mowiąc nie wiedzialem jak to rozdzielic aby set byl prywatny a get publiczny - a to takie proste...

Natomiast czy kolejne pomysły dot. tablicy bitmap w konstruktorze nie są przypadkiem mieszaniem GUI z logiką w jednej klasie? Nie zrozum mnie źle, bo to co piszesz brzmi logicznie tylko, jak pisalem wczesniej jestem na tym punkcie przewrażliwiony a chcialbym doprowadzić ten mikroprojekt do naprawdę idealnej postaci ;)
Mef
New member
 
Posty: 7
Dołączył(a): Śr lis 07, 2012 10:00 pm

Re: Idealne programowanie obiektowe

Postprzez xxSlayeRxx » Cz lis 08, 2012 9:03 pm

idea prograowania obiektowego jest to, ab kostka sama potrafila sie narysowac :D

to nie jest laczenie gui z kodem, to jest wlasnie separacja... mozesz zrobic np klase ktora bedzie ci robic kostki ( Kostki.DajCzerwonaKostke() zwraca kostke z czerwonymi bokami itd bitmapa jest zasobem


prosciej nie umiem tego wytlumaczyc... myllisz troche pojecia
elementem gui jest combobox z nazwiskami, ale nazwiska nie sa elementeem gui... tak samo mozna powiedziec o pictureboxie i kostce.

jakbys zamiast oobrazka zwracal liczbe oczek to byloby to gui wg Ciebie? pewnie nie, ale ta 1, 4 czy 5 tez jakos trzeba narysowac nie?, wiec jednak gui?
xxSlayeRxx
Member
 
Posty: 661
Dołączył(a): Pt lip 08, 2011 10:24 pm

Re: Idealne programowanie obiektowe

Postprzez Day7 » Cz lis 08, 2012 9:23 pm

Obiekt Random powinien być zainicjowany w konstruktorze. Ponowna inicjacja przy losowaniu zakłamuje wynik. Wg. mnie powinieneś trzymać wartość poprzedniej animacji losowania, żeby się nie powtarzała. Załóżmy że 10x Random wylosuje 1 - fajnie to wygląda? (wiem że szansa na to jest jak wygrana w totku, obrazuję tylko przykład)

Gdy dodajesz wartość numeryczną do string nie używaj metody ToString();

Sleep daj przed losowaniem, żeby przycisk przywrócić do stanu Enabled razem z końcem losowania.

Application.DoEvents(); na koniec pętli. - przyciśnij przycisk Pokulaj w trakcie losowania kilka razy. Ta metoda usunie ten bug.

Deklaracje wewnątrz metod rób z var (łatwiej pozwala śledzić deklaracje lokalne).

Wywołuj klasę obiektu przy pomocy "as" gdy to możliwe.

Rozdzielaj pola i właściwości konstruktorem, kolejnością zgodnie z modyfikatorem.

Metoda Refresh po zmianie właściwości Image jest niepotrzebna, jeśli DoEvents jes wywoływana.

3 ostatnie etapy animacji losowania ładnie Ci spowolni warunek i > 7. 500/30 kompilator zoptymalizuje do 16 automatycznie, wiec ta matma tam niepotrzebna.

"this" używamy gdy lokalne pole koliduje z zadeklarowanym w klasie, najlepiej tego unikać. Lokalne pola nazywaj naPrzykladTak, prywatne pola klasy _naPrzykladTak, publiczne NaPrzykladTak.

Generalnie ja bym wszystko wywalił z metody zdarzenia do oddzielnych metod. Tak widać w zdarzeniu co dzieje się w przypadku działania po przez nazewnictwo metod.
Załączniki
KostkaDoGry.7z
(22.02 KiB) Pobrane 284 razy
Avatar użytkownika
Day7
Member
 
Posty: 288
Dołączył(a): Wt paź 12, 2010 11:14 am
Lokalizacja: Bielsk Podlaski

Re: Idealne programowanie obiektowe

Postprzez Mef » Cz lis 08, 2012 11:24 pm

@xxSlayeRxx - ok, zaczynam trybić ;)

@Day7 - wlasnie tego potrzebowałem - dzięki wielkie za poświęcony czas i poprawiony kod. Jutro (czyli dziś) po pracy zamierzam dokładnie rozkminić każdą zmianę, którą wprowadziłeś. Póki co zdązylem stwierdzić jedynie, że każda z nich jest jak najbardziej uzasadniona. Prawdopodobnie będę miał też kilka pytań ale postaram się zredukować ich ilość do minimum za pomocą google.com.

BTW. Ostatnią godzinkę poświęciłem na zrobienie minigry z tej wczorajszej kostki (z błędów sam zauważylem jedynie Random w zlym miejscu..). Jednak wskutek ilości zmian, które wprowadziłeś już widzę, że mimo, iż pewnie popełniłem nowe błędy/nieścisłości to będę musiał i tak jeszcze przewrócić klasę Kostka do góry nogami.

Niemniej jednak bardzo się cieszę, z takiego obrotu sprawy. Oby tak dalej ;)
Mef
New member
 
Posty: 7
Dołączył(a): Śr lis 07, 2012 10:00 pm

Re: Idealne programowanie obiektowe

Postprzez Day7 » Pt lis 09, 2012 12:36 am

Bajera :lol:
Załączniki
KostkaDoGry.7z
(22.95 KiB) Pobrane 286 razy
Avatar użytkownika
Day7
Member
 
Posty: 288
Dołączył(a): Wt paź 12, 2010 11:14 am
Lokalizacja: Bielsk Podlaski

Re: Idealne programowanie obiektowe

Postprzez Mef » Pt lis 09, 2012 6:15 pm

ok, pytanka do Day7:

Rozdzielaj pola i właściwości konstruktorem, kolejnością zgodnie z modyfikatorem.

0. Nie czujesz, że rymujesz ;)
1. Dlaczego rozdzielać? Moim zdaniem czytelniej jest najpierw pola, pozniej wlasciwosci, na koncu konstruktor i metody.
2. Rozumiem, że chodzi o mod. dostępu - np. najpierw wszystkie publiczne, pozniej prywatne?

Deklaracje wewnątrz metod rób z var (łatwiej pozwala śledzić deklaracje lokalne).

Chodzi tylko o podkreslenie, że dana zmienna jest lokalna?


Generalnie ja bym wszystko wywalił z metody zdarzenia do oddzielnych metod. Tak widać w zdarzeniu co dzieje się w przypadku działania po przez nazewnictwo metod.

Czyli w tym przypadku chciałbyś porozbijać btn.._Click(... , ...) na mniejsze metody klasy Main?

---
Edit: Zalaczam kolejną wersję Kości w formie mikrogry. Część zmian zastosowalem, część musze przegryźć i się ustosunkować do nich a kilku rzeczy wiem, że nie chcę mieć (np. brak remisu - niezgodne z rzeczywistością). Denerwuje mnie ilość bezparametrowych metod w klasie Main - co proponujecie z tym zrobić? Być może klasa Sędzia, która rozlicza wyniki?

W najbliższej przyszłości postaram się zrobić samorysującą się klasę Kostka, wedle wskazań xxSlayerxx i podarować każdemu z graczy własną (niepowtarzalną) koche ;) W razie nadmiaru wolnego czasu chciałbym podłapać również którąś z powojennych technik programowania grafiki (czyli chyba XNA) i zrobić prawdziwe kulające się kostki. Na studiach miałem OpenGL i była z tego duża radocha, jednak o XNA nie wiem absolutnie nic.
Załączniki
Kosci(v0.2).zip
(62.62 KiB) Pobrane 316 razy
Mef
New member
 
Posty: 7
Dołączył(a): Śr lis 07, 2012 10:00 pm

Re: Idealne programowanie obiektowe

Postprzez LaM » Wt sty 01, 2013 9:41 pm

Przejarzalem kod i dorzuce swoje 3 grosze.

1. Oducz sie uzywania jezyka polskiego w kodzie zrodlowym (dobrze jak nawet w komentarzach przestaniesz). Angielski to podstawa i period. Kazda szanujaca sie firma uzywa tylko angielskiego zawsze i wszedzie.

2. Metoda DodajPunkt zmienilbym nazwe na InkrementujPunkt. Dodaj punkt wskazuje na to ze funkcja ma 1 parametr ktorym jest punkt. InkrementujPunkt jasno wskazuje zamiar.

3. Wszelakie stringi uzywane w aplikacji bedace stalymi powinenes deklarowac na poczatku klasy przed constructorem. Do tego jasno zaznaczyc kompilatorowi ze to jest const. Przy obecnym rozwiazaniu on sam to zoptymalizuje i zrobi te consty ale ... dzieki wyrzuceniu wszystkich deklaracji takich stringow na poczatku kod staje sie czytelniejszy.

4. Przenes taka inicjalizacje do konstruktora.
Kod: Zaznacz cały
       
 Kostka kostka = new Kostka(6);
        Gracz user = new Gracz();
        Gracz komp = new Gracz();


5. Ten kod powinen byc wydzielony do oddzielnej metody ktorej nazwa wskazywala by na sens takiego dzialania. Teraz to niewiadomo o co chodzi :)
Kod: Zaznacz cały
Thread.Sleep(i*(i < 7 ? 1 : 2)*20);


6. Rowniez wydziel to do oddzielnej metody cos ala GetActualImage

Kod: Zaznacz cały
pictureBox1.Image = Properties.Resources.ResourceManager.GetObject("_" + kostka.AktualnieWylosowano) as Bitmap;
LaM
Member
 
Posty: 118
Dołączył(a): Pn cze 08, 2009 8:01 pm
Lokalizacja: London

Re: Idealne programowanie obiektowe

Postprzez Mef » N sty 20, 2013 9:11 am

Wielkie dzięki za wskazówki, z pewnością wezmę je pod uwagę. Jest jednak jeszcze jedna sprawa, która mnie bardzo blokuje i nie mogę znaleźć 'idealnego' ani nawet rozsądnego rozwiązania.

Jak powszechnie wiadomo: klasy powinny być najbardziej samowystarczalne jak tylko to możliwe. Obiekty klas w wielu przypadkach mają swoją graficzną reprezentację (w programie trzeba je narysować). Jestem zwolennikiem teorii, że o ile to możliwe to nie obiekt powinien sam się rysować tylko wystarczy, że wie jak wygląda (przechowuje informację o swoim wyglądzie np. w postaci bitmapy) lecz niech COŚ INNEGO go rysuje.

Bardzo często mam sytuację, że konkretny obiekt da się reprezentować za pomocą zestawu standardowych kontrolek np. PictureBox+Label. Sensowne wydawałoby się umieszczanie tych kontrolek jako pola danej klasy, ich inicjalizacja w konstruktorze i mam fajny efekt: tworzę nowy obiekt a on sam się narysował (czyli utworzyły się odpowiednie PictureBox i Label). Jednak nigdy nie widziałem czegoś takiego na czyimś diagramie klas, bo zazwyczaj są tam proste typy jak int, string. A więc czy to forma ma rysować każdy mój obiekt?

Poniżej widać konkretny przyklad - screen programu, który napisałem po wiejsku (w borlandowy sposób) dawno temu. W tym przypadku właśnie umieściłem te kontrolki w klasie Album, co wymusiło zastosowanie brzydkich sztuczek z ich pominięciem przy serializacji tych obiektów.

Obrazek

Inny przykład to StickyNotes własnej roboty, gdzie karteczką jest forma z polem textowym rozciągniętym na cały obszar roboczy - tym razem w klasie StickyNote zawarłem kontrolki Form i TextBox z braku pomysłu na lepszą opcję.

Obrazek
Mef
New member
 
Posty: 7
Dołączył(a): Śr lis 07, 2012 10:00 pm

Re: Idealne programowanie obiektowe

Postprzez xxSlayeRxx » N sty 20, 2013 10:08 am

powinienes miec w klasie nie picturebox, a sam obrazek oraz string z tekstem,
nastepnie bierzesz tak: Rysuj(picturebox, label) i on uzupelnia te pola (czyli do pb wstawia obrazek, a do label wstawia tekst...

a najlepiej sie przerzuc na WPF'a i ten cel osiagniesz praktycznie bez kodu wlasnego, robisz listboxa (badz innego stackpanela) i w nim wpisujesz jako data template pb i label, nastepnie bindujesz do nich pozycje z klasy: obraz i podpis, a w kodzie listbox.datasource = lista; i wszystko
xxSlayeRxx
Member
 
Posty: 661
Dołączył(a): Pt lip 08, 2011 10:24 pm

Re: Idealne programowanie obiektowe

Sponsors

Sponsor
 


Powrót do Projekty i kody źródłowe

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 2 gości