Programowanie obiektowe - kiedy klasa, a kiedy nie?


(Lightextract) #21

@hindus udzieliłeś dość fajnej i niekrótkiej odpowiedzi, szkoda tylko że tak późno. mordesku i LonngerM dość dobrze rozjaśnili mi całą sprawę :P Domyśliłem się po przeczytaniu Twojego pierwszego posta, że “Pojemność” też będzie można użyć w pewnym kontekście, jednak nieco celowo pominąłem właśnie ten kontekst.

 

@mordesku  i tym samym udzieliłeś mi wyczerpujących odpowiedzi, wraz z LonngerM  :slight_smile:


(mikolaj_s) #22

@Luki_2

O jakim języku w ogóle mowa? Tak zadane pytanie sugeruje, że nie zdecydowałeś się jeszcze czy masz pisać w C czy C++. W tym ostatnim sprawa jest jasna. Po to są klasy, aby ich używać. W C również dobre wzroce każą używać struktur i funkcji operujących na tych strukturach. Dodanie metody do klasy czy nawet struktury powoduje większy porządek w kodzie, choć Linus Torvalds ma inne zdanie na ten temat :wink: Ale dla mnie pałętanie się luźnych funcji i struktur po całym programie jest brakiem porządku.

IMHO musisz się zdecydować czy chcesz pisać obiektowo czy proceduralnie. Najgorzej jest mieszać te dwa podejścia i tak sobie myślę, że niechęć Linusa do C++ bierze się właśnie z takiego pomieszanego kodu w połączeniu ze słabą znajomością samego C++.

 

A może raczej miałeś na myśli jak duży zakres funkcjonalności ma mieć dana klasa i czy zamiast pisać nową klasę lepiej dodać funkcjonalność do istniejącej? To już jest trudna sztuka, bo można podchodzić do problemu bardzo ortodoksyjnie obiektowo i natworzyć mnóstwo klas tak jak w Javie mamy całe multum klas związanych ze strumieniami i operacjami wejścia i wyjścia, a potem ciężko się w tym połapać, albo przeciwnie można przegiąć w drugą stronę tworząc klasy olbrzymy odpowiedzialne za wszystko. Umiejętność oceny i właściwego wyboru przychodzi zapewne z czasem, każdy by chciał od razu umieć to robić, a nie zdobywać doświadczenia w boju :wink: W przypadku projektowania klas zasada jest dobrze znana i prosta. Klasa nie może zbyt duża, lepiej aby robiła jedną rzecz dobrze. Dobrym sposobem jest zastanawianie się nad nazwą klasy. Jeśli nie potrafisz nazwać ją  prostym słowem to raczej robisz źle, czyli tworzysz KotoPsa jakbyśmy przełożyli to na język tutoriali :wink:


(somekind) #23

 

Taka prosta, że powstały chyba setki książek o tym, jak projektować obiektowy kod.

 

@Luki_2, masz jakieś dziwne przekonania, że klasy to rzeczy, albo że tworzy sie je, gdy mogą istnieć więcej niż raz. To jakieś dziwne zabobony.

Ilość instancji danej klasy w ogóle nie ma znaczenia. Klasy się tworzy, gdy są potrzebne, pewnym wyznacznikiem są zasady SOLID, OOA&D czy wzorce projektowe, trochę bardziej rozwiniętym podejście Domain Driven Design.

Poza tym jest wiele rodzajów klas:

  • realizujące jakiś algorytm;

  • zapewniające komunikację ze światem zewnętrznym (operacje na blikach, sieci, bazie danych);

  • opisujące dane trzymane w pliku/bazie, przesyłane przez sieć albo wyświetlane użytkownikowi;

  • stanowiące po prostu grupę powiązanych ze sobą wartości.

i żadna z nich nie jest “rzeczą”. Po prostu nie ma żadnej relacji między istniejącymi w rzeczywistości “rzeczami” a klasami w kodzie programu.


(KamilDz) #24

Nie do końca, ludzie stykają się w rzeczywistości z obiektami i klasami obiektów, więc są przyzwyczajeni do takiego myślenia, co powoduje że  programowanie obiektywne jest bardziej zgodne z ich umysłem. Ale nie musisz tego tak używać. Traktuj klasę jako pojemnik na powiązane zmienne i funkcje które przeprowadzają na nich operacje.

Funkcja nie powinna być dłuższa niż pojemność ekranu. Jak jest dłuższa to ją dzielisz.

W języku Java wszystko jest w klasach (pomijając typy proste). Z tego co rozumiem masz problem czy dany problem rozwiązywać za pomocą jednej klasy czy wielu. Nikt Ci na to nie odpowie, bo wszystko zależy od problemu i inżynieria oprogramowania to nie inżynieria budowlana. Powiedzmy sobie szczerze, inżynieria oprogramowania  z inżynierią ma wspólną tylko nazwę.:wink:

Jak korzysta się z wielu klas to powstaje problem czy klasa powinna mieć w sobie inne klasy czy po prostu dziedziczyć inne klasy. Nigdy nie stosuj dziedziczenia z wielu klas (w Javie nawet nie jest to możliwe).

Klasy pełnia funkcję opisową i zastępują komentarze (nazwa klasy ma nazwę w języku ludzkim). Do tego łatwiej znaleźć daną funkcję (metodę), po prostu wpisuje się nazwę obiektu, stawia kropkę i IDE podpowiada metody.

Możesz stosować klasy nawet kiedy raz ich używasz. Stworzenie klasy niewiele kosztuje po prostu otaczasz zmienne i funkcje nawiasami i wpisujesz przed tym class i jej nazwę.

Oczywiście funkcji w c++ nie musisz ładować do klas, możesz je załadować do przestrzeni nazw.


(Rolek0) #25

O obiektowości

class Fish extends Animal?

:wink:


(Lightextract) #26

@mikolaj_s  nie mam na myśli żadnego z tych języków. Temat jest bardzo luźno powiązany z językiem w którym piszę, tym bardziej że język ten opiera się na prototypach, a nie klasach. Dlatego też można powiedzieć, że temat założyłem nie w celu powiązania go z konkretnym językiem, a w celu dowiedzenia się tego, na co w sumie odpowiada drugi link Rolek0  oraz w swoim poście somekind.

 

@Rolek0 Ja akurat na ten artykuł podany w linku nie trafiłem, choć tytuł kojarzę z Google. Prawdopodobnie tytuł uznałem za niepowiązany z moim tematem i artykułu nie “odwiedziłem”, choć ten pytajnik na jego końcu powinien dać mi jednak do myślenia :stuck_out_tongue: Link ten wiele wyjaśnia i w sumie porusza dokładnie ten problem z którym borykałem się ja, a rozwiązanie dzięki mordesku  czy  LonngerM stało się dość proste - nie wgłębiać się aż tak we wszystko, tworzyć klasy kiedy uważa się to za stosowne przy czym mieć na uwadze, że pisze się obiektowo i w celu uporządkowania wszystkiego. Link ten jednak wyjaśnia problem dosadnie i konkretnie, a nie “mniej więcej” - nawet jest tam wymieniona przyczyna takich “filozoficznych”, czyli także moich, rozważań tzn. artykuły i książki podające za przykłady kodu odzwierciedlające rzeczywistość (Person, Animal, Car) utarły we mnie przekonanie o którym pisał somekind. Faktycznie jest tak, że programowanie obiektowe ma jedynie luźno odwzorowywać rzeczywistość dla wygody i porządku, łatwego rozwoju, a nie ściśle.

 

Pytanie zadane w tytule tematu jest dość ogólne i poniekąd pyta o to w jaki sposób projektować obiektowy kod, a konkretnie klasy w nim. Pyta się o to od strony “filozoficznej”, ale także pod kątem technicznym i projektowym na tyle dobrego rozpracowania klas, żeby zaraz nie było potrzeby kasowania jakiejś z nich w kodzie, albo zmieniania jej w sporym stopniu. To jednak jak niektórzy wyżej zauważyli słusznie, wymaga praktyki, a ja głupio chciałbym od razu wszystko robić doskonale zdając sobie sprawę, że to wymaga wiedzy, ale zapominając, że wymaga właśnie praktyki, prób i błędów.

 

“Boję” się zrobić coś źle i w efekcie myślę nad tym x czasu z minimalnymi efektami, a przez taki właśnie czas już powinienem przeprowadzić sporo prób zamiast tyle rozważać i myśleć, gdzie to te próby w gruncie rzeczy właśnie odpowiedzą na moje pytania. A uzasadniam sobie to tym, że chcę być jak najdokładniejszy zanim coś zrobię. To jest już mój problem z samym sobą, wiem jakie jest jego podłoże i sięga ono aż do mojego dzieciństwa - wychowania, otoczenia, pewnych “pesymizmów”, trochę mentalności polskiej.