Autor Wątek: Wzorzec projektowy  (Przeczytany 17840 razy)

Offline hashedone

  • Użytkownik

# Czerwiec 27, 2012, 14:54:47
@Cocomide - żeby uniknąć takiego rzutowania unika się wzorca fabryka. Takiego rzutowania nie będzie, jeśli nie będziesz wprowadzać dziedziczenia tam, gdzie nie ma polimorfizmu. Jeśli potrzebujesz w runtime rozpoznawać typ obiektu, dziedziczenie się do tego nie nadaje - nadaje się za to wzorzec Entity z polem "type" opisującym typ obiektu. I nie musisz tworzyć w obiekcie Entity pól nieużywanych. Spojrzałeś w ogóle na implementację tego wzorca którą umieścilem gdzieś w połowie tego wątku (druga strona, trzeci post)?
@Karol - oczywiście że mogę programować obiektowo bez klas. Zarówno WinAPI jak DX to biblioteki obiektowe, a nie używają klas. OOP to enkapsulacja + hermetyzacja + polimorfizm. Klasy w C++ są narzędziem pozwalającym wszystkie trzy łatwo osiągnąć, ale można je osiągnąć także bez użycia klas. Podobnie jak można używać klas tylko do enkapsulacji i unikać hermetyzacji i polimorfizmu (co jest najczęstszym błędem początkujących amatorów OOPu). A programowanie strukturalne to zupełnie co innego niż programowanie z użyciem struktur i przesyłanie ich jako argumentów funkcji - programowanie strukturalne jest wtedy, kiedy dane nie są grupowane, używa się dużo danych globalnych, a przepływ regulują luźno powiązane ze sobą funkcje (i nie, nie ma to związku z programowaniem funkcyjnym).

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Czerwiec 27, 2012, 15:05:20
Cytuj
Zarówno WinAPI jak DX to biblioteki obiektowe, a nie używają klas.
DX cały składa się prawie wyłacznie z klas, a w WinAPI obiektowości za grosz nie zauważyłem. :)

Offline koirat

  • Użytkownik

# Czerwiec 27, 2012, 15:27:16
Według wiki warunkiem koniecznym  OOP (object oriented programming)  jest używanie obiektów, czyli struktur danych posiadających pola oraz metody na nich operaujące. Wszystko inne (dziedziczenie, polimorfizm itp) to dodatek.

Więc pytanie czy taki własnoręczny OOP tworzony bez wsparcia ze strony języka rzeczywiście jest OOP-em.

WinApi kilka groszy z obiektowości tam było, podczas tworzenia okienek - można było nawet dziedziczyć po innych okienkach, superclassing czy jakoś tak się to nazywało. Pytanie czy to wystarczy aby być OOP. ;)

Offline Cocomide

  • Użytkownik

# Czerwiec 27, 2012, 16:08:28
@hashedone
Czytałem czytałem. Teraz dla mnie jasne jest użycie Unii. Niestety w C# jako tako Unie nie istnieją. Jakoś już to wygląda w mojej głowie. Tak czy siak nadal będę rzutował na interfejs i z tego działał. Jak ktoś chce to może mnie wyprowadzić z błędu ale dalej uważam to za bardziej efektywne i mniej zaśmiecające kod.

Offline hashedone

  • Użytkownik

# Czerwiec 27, 2012, 16:42:06
@Krzysiek K. - co do DX - zawsze tak było? Ja może po prostu zatrzymałem się na archaicznej wersji 9... (później już tylko OGL).

Offline yarpen

  • Użytkownik

# Czerwiec 27, 2012, 16:45:12
Zawsze.

Offline Kos

  • Użytkownik
    • kos.gd

# Czerwiec 27, 2012, 19:11:39
Więc jak chcesz programować obiektowo bez klas, bez których nie będzie obiektów?

Kto Ci powiedział, że bez klas nie ma obiektów? Obiekt = jakiś stan i logika (por. enkapsulacja) zamknięte pod pewnym dobrze zdefiniowanym interfejsem (por. hermetyzacja).
Klasa = nic więcej, niż konstrukt składniowy pozwalający zrobić łatwo fabrykę obiektów o szeregu cech wspólnych (typowy use case), przy okazji często niezła do organizowania kodu, a także upraszczająca pisanie kompilatora. :) Użyteczna rzecz, dlatego taka popularna - ale nie jest bezpośrednio elementem designu programów obiektowych, a raptem sposobem na implementację.
Taki JS sobie doskonale radzi bez klas, dając zamiast nich mechanizm droższy, ale i mocniejszy - prototypy. W Pythonie klasy są, ale są pełnoprawnymi obiektami.

Offline siso

  • Użytkownik

  • +3
# Czerwiec 27, 2012, 19:44:44
Widzę, że mój post wprowadził trochę zamieszania. Dla tych, którzy nie chcieli zobaczyć w nim ironii spieszę wyjaśnić, że był on ironiczny. Przedstawiony tam sposób to obecnie jeden z największych antywzorców programowania. Powinno się go używać tylko w jakichś ekstremalnych okolicznościach, jeśli w ogóle. Każdy więc kto pomyślał "od dzisiaj tak programuję!" powinien natychmiast odejść od komputera i zrobić 20 pompek za karę :)

Ze mną było tak: najpierw byłem fanem C, później fanem OOP w zastosowaniu "do wszystkiego", a teraz jestem fanem czystego kodu. Czysty kod można napisać w każdym języku, ale ciężko jest się tego nauczyć w językach, które nie oferują enkapsulacji. Weźmy takie C. Mamy struktury, w których wszystko jest publiczne. Mogę czymś takim zamodelować obiektowość? Jasne, ale muszę wykazać się wielką dyscypliną, żeby nie grzebać w wewnętrznym stanie obiektu, kiedy tylko mi się chce. Co innego, jeśli mi język tego zabroni. Dostaję po łapkach i nie robię brudnych rzeczy (albo przynajmniej robię mniej).

Kod, obojętnie z użyciem jakiego podejścia byśmy go nie pisali, oprócz właściwego nazewnictwa, powinien być osadzony w opisywanej przez siebie domenie oraz realizować zasadę SRP - jedna rzecz za jednym razem, mówiąc obrazowo, albo profesjonalniej: pojedyncza odpowiedzialność. Prowadzi to do jego strukturyzacji, co wpływa na czytelność i łatwość konserwacji, ponieważ zniechęca do tworzenia długich implementacji (metod, funkcji, procedur). Tworzymy krótkie funkcje realizujące proste, dobrze zdefiniowane rzeczy plus jakiś mały, prosty stan zamknięty w dobrze zdefiniowanych granicach - i już mamy obiekty. Dodamy funkcje wirtualne albo wskaźniki na funkcje - i już mamy polimorfizm. Ale to jest nieważne, bo najważniejsze, co mamy - pod warunkiem zastosowania odpowiedniego nazewnictwa - to kod pasujący do domeny. Bo chyba łatwiej jest rozmawiać o "obiektach gry" niż jakichś bezdusznych "encjach". Obiekt gry należy do jej domeny, a encja jest na tyle ogólnym pojęciem, że mogę ją wsadzić gdziekolwiek. Obiektowi gry mogę przypisać funkcje zdefiniowane na potrzeby tej gry, dla encji mogę zdefiniować dowolne rzeczy, bo co tak naprawdę jest potrzebne ogólnemu bytowi?

Właśnie dlatego podejście polegające na tworzeniu uproszczonych modeli domen, nieodzowne w OOP, zyskało sobie taką popularność.

Jeżeli początkujący programista nie będzie prowadzony ta ścieżką, to, drogi Krzyśku K. straci ją szybko z oczu. Dokładnie o tym pisałem wcześniej. Będzie tworzył kilometrowe funkcje, będzie pchał do struktur dziesiątki śmieci, będzie w tych śmieciach grzebał przy kazdej okazji i będzie robił jedno spaghetti na drugim. A jak mu już zabraknie konceptu, to zacznie jeszcze skakać przez goto.

Na etapie pisania małych gierek w domu nie powinno się nikogo zachęcać słowami "zrób tak, bo tak jest prościej, optymalnie i - co najważniejsze - skończysz to szybko". Powinno się zachęcać przez "rób tak, jak się powinno to robić - ucz się pisać czysto". Jeśli nawet i pięć projektów ma takiemu programiście upaść, ale wyciągnie on z tego lekcję czystego kodu, to lepiej, niż gdyby napisał te pięć koślawych gier w jakiś obleśny sposób.

Rzekłem.

Offline rm-f

  • Użytkownik
    • Tu trolluje

  • +2
# Czerwiec 27, 2012, 20:17:29
Jeśli nawet i pięć projektów ma takiemu programiście upaść, ale wyciągnie on z tego lekcję czystego kodu, to lepiej, niż gdyby napisał te pięć koślawych gier w jakiś obleśny sposób.
To stwierdzi: A w cholerę z czystym kodem jak do niczego nie dochodzę i napisze działająca grę w main+kilkanaście funkcji+ kilkanaście haków jak to wyglądała jedna z gier Vipy. :)

Offline Karol

  • Użytkownik

# Czerwiec 27, 2012, 20:18:56
Kto Ci powiedział, że bez klas nie ma obiektów?
A żebym pamiętał, ale od zawsze myślałem, że klasa jest swoistą definicją obiektu, a obiekt instancją klasy. Skąd ja/kompilator/interpreter ma wiedzieć, że np. obiekt X ma 3 inty, 2 stringi i 4 metody?

Offline siso

  • Użytkownik

# Czerwiec 27, 2012, 20:26:18
To stwierdzi: A w cholerę z czystym kodem jak do niczego nie dochodzę i napisze działająca grę w main+kilkanaście funkcji+ kilkanaście haków jak to wyglądała jedna z gier Vipy. :)
Nie sądzę, żeby Vipa był specjalnie dumny z kodu, w którym jest kilkanaście haków. Nie był to najlepszy przykład, świrus, niestety.

Offline Liosan

  • Moderator

# Czerwiec 27, 2012, 21:16:46
A żebym pamiętał, ale od zawsze myślałem, że klasa jest swoistą definicją obiektu, a obiekt instancją klasy. Skąd ja/kompilator/interpreter ma wiedzieć, że np. obiekt X ma 3 inty, 2 stringi i 4 metody?
Z prototypu. Spróbuj ogarnąć to, co uchodzi za obiektowość pod JavaScriptem.

Liosan

Offline rm-f

  • Użytkownik
    • Tu trolluje

  • +1
# Czerwiec 27, 2012, 21:27:21
Nie sądzę, żeby Vipa był specjalnie dumny z kodu
Sam może odpowiedzieć na to pytanie. :)

Offline Kos

  • Użytkownik
    • kos.gd

# Czerwiec 27, 2012, 21:49:49
A żebym pamiętał, ale od zawsze myślałem, że klasa jest swoistą definicją obiektu, a obiekt instancją klasy. Skąd ja/kompilator/interpreter ma wiedzieć, że np. obiekt X ma 3 inty, 2 stringi i 4 metody?
Na poziomie koncepcyjnym obiekt ma po prostu jakiś tam interfejs (np. zbiór metod lub propertasów), w jakiś tam sposób zrealizowany.
Na poziomie implementacyjnym wszystko zależy od języka i platformy. W C++ jeden obiekt jest ciągłym blokiem pamięci, więc potrzebujesz w momencie kompilacji znać jego wszystkie pola i ich długość. W JS czy Pythonie obiekt jest (czy raczej: bywa) po prostu hashmapą nazwa -> wartość/funkcja i nawet nie musi mieć tego samego zestawu pól przez całe życie. I teraz dla oszczędności, jeśli jest wiele podobnych obiektów, to prototypy w JS pozwalają wyciągnąć niektóre z ich wartości gdzieś wyżej: zapytanie obj.foo, w wypadku braku foo, zostanie oddelegowane do obj.__proto__.foo itd. Możesz sobie tym zamodelować nie tylko zwykłe dziedziczenie a'la C++, ale np. też dziedziczenie danych.

Chociaż, jeśli chcesz wiedzieć: dla wydajności JIT-y javascriptu (na pewno V8) robią to samo, co robi C++, tylko w locie: wykorzystują, że obiekt zwykle ma pewien stały zestaw pól, i generują w locie taką "klasę" (czy raczej: schemat) by obiekty mają stałą długość w bajtach. Działa. Jeśli takiemu obiektowi dodasz w runtime nowe pole, to mu się wygeneruje nowa "klasa". Nie potrzeba wcale do tego szczególnego wsparcia ze strony języka, to wyłącznie optymalizacja.

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Czerwiec 27, 2012, 22:52:14
Cytuj
Jeżeli początkujący programista nie będzie prowadzony ta ścieżką, to, drogi Krzyśku K. straci ją szybko z oczu. Dokładnie o tym pisałem wcześniej. Będzie tworzył kilometrowe funkcje, będzie pchał do struktur dziesiątki śmieci, będzie w tych śmieciach grzebał przy kazdej okazji i będzie robił jedno spaghetti na drugim. A jak mu już zabraknie konceptu, to zacznie jeszcze skakać przez goto.
No i co z tego? Albo wypracuje swój styl, albo wcześniej czy później spotka się z dominującym stylem "pchaj klasy wszędzie".

Cytuj
Na etapie pisania małych gierek w domu nie powinno się nikogo zachęcać słowami "zrób tak, bo tak jest prościej, optymalnie i - co najważniejsze - skończysz to szybko". Powinno się zachęcać przez "rób tak, jak się powinno to robić - ucz się pisać czysto". Jeśli nawet i pięć projektów ma takiemu programiście upaść, ale wyciągnie on z tego lekcję czystego kodu, to lepiej, niż gdyby napisał te pięć koślawych gier w jakiś obleśny sposób.
Swoją naukę pisania czystego kodu jeszcze odbierze. Czy to na studiach, czy z książek, czy tu z forum. Ale pisania na szybko nikt jakoś nie uczy, co jest dużym problemem.