Modulares Programmieren vs. OOP
-
SpaceMonkey schrieb:
aber oop muss nicht immer die erste wahl sein.
Hat auch niemand behauptet. Nur deine Argumentation ist etwas schwammig.
Wann ist denn Wartbarkeit nicht wichtig? In meinen Augen ist es das immer.
Oder deine Argumentation über private Member...wenn im moment der wartbarkeit oder der übersichtlichlichkeit keine bedeutung geschenkt wird und man allein an einem projekt arbeitet warum sollte man dann oo programmieren?
weil man mit OOP Sachen ausdrücken kann, die man ohne nicht kann (und umgekehrt natürlich auch)
Deshalb ist C++ ja eine Multiparadigmen Sprache - man kann OOP und Prozeduale Programme schreiben
würde ja nur zeit verschwenden...
wieso?
OOP hat doch keinen Mehraufwand - zumindest nicht generell. Sicher gibt es Sachen die man gerade zB Functional wesentlich eleganter und besser hinbekommt - aber generell sehe ich nirgends einen Mehraufwand.
-
wartbarkeit darf meiner meinung nach nicht im mittelpunkt stehen.ich schreibe nicht ein programm um dafür gleich einen nachfolger programmieren zu müssen
bin mit meinem programm jetzt beschäftigt und nicht mit der zukunft. es mag hier sicher projekte geben bei denen man an die zukunft denken muss
warum auch an die zukunft denken ich bin ja schließlich mit meinem akutellen programm beschäftigtigt und mit keinem anderen.
ja es gibt sicher situationen in denen man mit oo besser aufgehoben ist. zum beispiel wenn man echt objekte hat die aufeinander aufbauen.
aber solch eine situation muss ja nicht immer geltenoop kann einen schon einschrenken wenn man an einem problem arbeitet. warum sollte ich auch eine klasse definieren wenn es auch mit structs geht.
auch direkt einfach darauflosprogrammieren ist mit oop sicher schwerer
-
sorry, aber kannst du auch Argumente bringen warum es mit OOP komplizierter ist, als ohne?
sicher - um unwartbaren spaghetti code zu schreiben, eignet sich prozeduale programmierung mehr, da man eher dazu verleitet wird.
erklär mal, was du an OOP nicht leiden kannst. mir ist es nicht ganz klar.
du sagst:
du brauchst keine wartbarkeit
du brauchst keine privaten-Elemente (dies bedeutet, dass du keine kapselung brauchst)
code redundanz ist egal für dich
sinnvolle strukturieren ist anscheinend auch egal (?)wie steht es mit typensicherheit? abstraktion? und vorallem Fehlerfreien code (das stelle ich mir ohne gute struktur recht schwer zu realisieren vor)
erklär mal was für dich wichtig ist, vielleicht verstehe ich deine argumente dann besser...
PS: Ich behaupte nicht, dass OOP besser oder schlechter ist. ich will nur verstehen was du an OOP nicht magst.
-
nein ich glaube du hast mich falsch verstanden. ich würde nicht wagen zu behaupten dass oop schlecht sei. ich will nur sagen dass es für mich einfach ein bisschen umständlich ist. so wenn ich jetzt zum beispiel ein paar variablen zusammenfassen und mit diesen variablen in meiner hauptschleife sehr viel spielen muss so müsste ich wenn ich oo programmieren würde eine klasse erzeugen die variablen die ich brauche in die klasse aufnehmen und um auf diese variablen zugreifen zu können müsste ich extra funktionen wie set_x(int _x) oder get_x() schreiben und das nur um auf die variable zugreifen zu können.
wenn ich jetzt nun in der hauptschleife mit diesen variablen berechnungen durchführen will müsste ich immer wieder die funktion get_x angeben um die variable x aus meiner klasse zu bekommen. das ist mir zum beispiel einfach zu umständlich und lege lieber ein struct an um dann direkt mit der variablen sprechen zu können.
klar ist diese art eher dreckig aber ich lege keinen wert auf schönheit des codes sondern die berechnungen in der hauptschleife sind mir wichtig und nicht das objektorientierte konzept. konzept soll ja schließlich einem helfen und nicht behindern.
-
SpaceMonkey schrieb:
so wenn ich jetzt zum beispiel ein paar variablen zusammenfassen und mit diesen variablen in meiner hauptschleife sehr viel spielen muss so müsste ich wenn ich oo programmieren würde eine klasse erzeugen die variablen die ich brauche in die klasse aufnehmen und um auf diese variablen zugreifen zu können müsste ich extra funktionen wie set_x(int _x) oder get_x() schreiben und das nur um auf die variable zugreifen zu können.
OOP != alles in Klassen packen
Es spricht nichts dagegen diesen Loop genauso wie bisher zu machen. Nur uU representieren ein paar variablen gemeinsam ein Objekt, zB Spieler
Wenn du jetzt Spieler einen schritt nachvorne machen lassen willst, schreibst du statt
if(spieler_sicht==NACH_OBEN) ++spieler_y;
else if(spieler_sicht==NACH_UNTEN) --spieler_y;
else if(spieler_sicht==NACH_LINKS) --spieler_x;
else if(spieler_sicht==NACH_RECHTS) ++spieler_x;einfach
spieler.moveForward();es bedeutet aber nicht, dass alles einfach in klassen gepackt wird.
klar ist diese art eher dreckig aber ich lege keinen wert auf schönheit des codes sondern die berechnungen in der hauptschleife sind mir wichtig und nicht das objektorientierte konzept. konzept soll ja schließlich einem helfen und nicht behindern.
ich glaube ganz ehrlich, dass du dich noch nicht mit OOP auseinander gesetzt hast. zumindest hat nichts von dem was du gesagt hast so geklungen als hättest du dich länger ordentlich mit OOP befasst.
wenn dir OOP nicht liegt, oder du es nicht magst: kein Problem.
Aber dann erzähl auch nicht so sachen wie dass man 'extra ne methode schreiben um auf variablen zugreifen zu können' oder dass man mit structs flexibler ist (denn genau da hat dir Helium ja das gegenteil bewiesen - es sei denn du kapselst es schön in funktionen, dann kannst du einige c++ features simulieren, aber zB virtuelle methoden nicht) oder dass du von 'OOP in Büchern' abraten würdest...wenn du OOP nicht magst: OK - aber bitte keinen quatsch erzählen (oder zumindest genau begründen)
-
logisch was ist schöner?
if(spieler_sicht==NACH_OBEN) ++spieler_y; else if(spieler_sicht==NACH_UNTEN) --spieler_y; else if(spieler_sicht==NACH_LINKS) --spieler_x; else if(spieler_sicht==NACH_RECHTS) ++spieler_x;
oder
spieler.moveForward();
frage?
angenommen dein spieler müsste vorwärts laufen aber es könnten vor ihm jede menge objekte liegen die ihn behindern. wie prüfst du jetzt in deiner funktion nach ob vor ihm ein objekt liegt?
-
In der OO-Variante würdest du das nur in Player::moveForward ändern. Ansonsten musst du jeden Code ändern, der direkt auf x/y zugreift. Das ist potenziell viel mehr.
Das heißt natürlich, dass Player von den anderen Objekten wissen muss. Solche "muss wissen von"s, die meistens mindestens eine Extra-Referenz bedeuten, sind meistens das, was mich zu structs treibt, die von eigentlich unbeteiligtem Code verarbeitet werden. Bei so wichtigen Objekten wie dem Spieler würde ich das aber nicht als Argument zählen lassen :p
-
SpaceMonkey schrieb:
so wenn ich jetzt zum beispiel ein paar variablen zusammenfassen und mit diesen variablen in meiner hauptschleife sehr viel spielen muss
[...]
klar ist diese art eher dreckig aber ich lege keinen wert auf schönheit des codes sondern die berechnungen in der hauptschleife sind mir wichtig und nicht das objektorientierte konzept. konzept soll ja schließlich einem helfen und nicht behindern.Und eine 200-Zeilen-Funktion mit fast globalen Variablen behindert nicht?!
Oh gott, ich hoffe der Code den du schreibst, verlässt niemals deine Festplatte...
-
SpaceMonkey schrieb:
wartbarkeit darf meiner meinung nach nicht im mittelpunkt stehen.ich schreibe nicht ein programm um dafür gleich einen nachfolger programmieren zu müssen
Wartbarkeit heißt auch (IMO in erster Linie) vorhandene Bugs zu beseitigen etc und nicht in erster Linie auf den nächsten Major-Release zu schielen.
-
operator void schrieb:
Das heißt natürlich, dass Player von den anderen Objekten wissen muss. Solche "muss wissen von"s, die meistens mindestens eine Extra-Referenz bedeuten, sind meistens das, was mich zu structs treibt, die von eigentlich unbeteiligtem Code verarbeitet werden. Bei so wichtigen Objekten wie dem Spieler würde ich das aber nicht als Argument zählen lassen :p
Generell muss Player aber nur von einer Basisklasse wissen. Danach kann es heute eine Wand sein gegen die ein Spieler läuft, aber morgen schon ein ganzes Haus. Du könntest z.B. der Wand gegen die der Spieler rennt den Spieler Übergeben und dafür sorgen das die Wand eine Methode kollision aufruft und sich selbst als Basisobjekt übergibt. Das machste bei Haus genauso, bei Hochhaus auch und bei Bretterbude ebenfalls. Ohne für die nachträglchen Häulse Spieler aber auch nur anfassen zu müssen.
Die Erfahrung die ich beim "Kampf" OOP VS Modulare Programmierung in der Firma gemacht habe ist, das sich keiner gedanken um das Projekt vor der Programmierung machen wollte. Lieber gleich loslegen, ohne Planung. Und dafür ist OOP nun mal nicht geeignet.
-
Was soll an spieler.move_forward() so toll sein? In einer prozeduralen Welt wie C könnte man das gleiche durch player_move(&spieler) erledigen. Dass die Entscheidungslogik nicht an irgendeine beliebige Stelle gehört, sondern in eine eigene Funktion gehört, darauf sind schon andere vor der OOP gekommen.
An sich würde mich aber schon interessieren, ob irgendeiner von denen, die hier auf SpaceMonkey einschlagen, schonmal ein nicht-triviales Spiel programmiert hat, dass unter den Design-Maßstäben, die er hier im Thread anlegt, bestehen könnte. Ich würd dann gern den Source (oder UML oder was) dazu sehen, lerne nämlich gern dazu
-
Bashar schrieb:
Was soll an spieler.move_forward() so toll sein? In einer prozeduralen Welt wie C könnte man das gleiche durch player_move(&spieler) erledigen.
Natürlich ist das egal. Mir ging es dabei eher darum die Kapselung zu erläutern.
Denn wir sind uns ja wohl einig dass eine Move-Funktion wichtig ist - um Objekte zu bewegen und dass man nicht direkt die x und y Werte des Objektes ändern sollte, oder?
Genau das wollte ich zeigen - schließlich geht es hier nicht um OOP vs Prozedualer Programmierung, sondern so wie ich SpaceMonkey verstanden habe - hat er keine struktur in seinem code.
Ich hoffe auch, dasss wir uns einig sind, dass es egal ist ob man OO, Prozedual, Funktional oder sonstwas programmiert - da generell alle Methoden Sinn machen (Ausnahme: spezielle Probleme, fordern spezielle Lösungen)
-
programmteile die öfter vorkommen in funktionen zu packen mag sicher sinnvoll sein aber das ist ja hier nie zum thema gestanden oder? die x und y werte nie direkt ändern ist ja das konzept der oop
manchmal kann es eben aber auch ganz nett sein wenn man x und y werte der klasse/struct direkt ändern kann besonders eben bei solchen problemen wie kollision oder wenn mehrere spieler gegeneinander laufen. klar mit oop könnte man das sicher auch lösen aber ich will das problem eben direkt angehen und keine klassen erzeugen. für manche hier mag das mit den klassen sicher einfacher und übersichtlicher sein ich will aber direkt mit den werten spielen und wenn teile öfter vorkommen pack ich den code dann in funktionen. zum beispiel initspieler um startwerte zu setzen oder eben zum beispiel die movefunktion. aber eben das ergebnis oop und prozedural ist das gleiche.
struktur in seinen code zu bekommen kann man auch später erledigen jeder hat eben eine andere arbeitstechnik aber ich bastle eben einfach herum schreibe in meiner hauptschleife füge oben wenn nötig funktionen hinzuund später kann ich das ganze dann in dateien packen. andere schauen hier gleich auf struktur ich eben nicht. jeder wie er will
-
ich glaube es lohnt sich nicht mit SpaceMonkey weiter zu diskutieren.
-
ist richtig
-
SpaceMonkey, mit Deiner Argumentation kommst Du mir vor, wie ein Affe der durch's All fliegt...
Muahahaha, spitzen Gag, oder?!? ...
-
Bashar schrieb:
Was soll an spieler.move_forward() so toll sein? In einer prozeduralen Welt wie C könnte man das gleiche durch player_move(&spieler) erledigen. Dass die Entscheidungslogik nicht an irgendeine beliebige Stelle gehört, sondern in eine eigene Funktion gehört, darauf sind schon andere vor der OOP gekommen.
Ich habe SpaceMonkeys Anfangspostings nicht so verstanden, dass er nur Probleme mit der OO hat, sondern mit Kapselung allgemein - immerhin will er ja direkt mit den Werten spielen. Da er das innerhalb der Klasse ja problemlos kann, will er es scheinbar auch von außerhalb -> hat auf mich nicht gerade zentralisiert gewirkt.
Ich code auch oft genug mit structs drauflos, die sich dann allmählich in Objekte verwandeln - oder auch nicht. Mischlinge erlaubt C++ ja problemlos, aber gerade deshalb verstehe ich nicht, warum man nicht zumindest Teil-OO benutzen kann. Warum initspieler wenn ein Konstruktor genausoviel Schreibarbeit wäre?
Und naja, unfertige Spiele zählen nicht, oder?
Mittlerweile habe ich es aufgegeben, nur mit der OO zu arbeiten, ohne Vererbungstemplates komme ich nicht weit...
-
ja innerhalb der klasse kann ich sicher mit meinen werten spielen wie ich will. wenn aber eben von außerhalb auch werte gebraucht werden wie jetzt bei der methode moveforward dann tut man sich halt etwas schwerer mit oo. klar ist es auch machbar aber mit structs stellt sich dieses problem erst gar nicht.
[quote]
Ich code auch oft genug mit structs drauflos, die sich dann allmählich in Objekte verwandeln - oder auch nicht. Mischlinge erlaubt C++ ja problemlos, aber gerade deshalb verstehe ich nicht, warum man nicht zumindest Teil-OO benutzen kann. Warum initspieler wenn ein Konstruktor genausoviel Schreibarbeit wäre?
[cpp]dem kann ich voll zustimmen. ich programmier einfach auch drauf los später kann man das ganze ja dann in klassen und dateinen packen. ob ich jetzt ne funktoin initspieler oder nen konstruktor verwendet ist egal oder? wegen dem konstruktor ist oo nicht besser und nicht schlechter
-
SpaceMonkey schrieb:
wenn aber eben von außerhalb auch werte gebraucht werden wie jetzt bei der methode moveforward dann tut man sich halt etwas schwerer mit oo.
Man muss sich IMHO nicht mehr Gedanken machen als ohne... Ein System ausdenken, über das alle Objekte miteinander kommunizieren, muss man sich so oder so.
ob ich jetzt ne funktoin initspieler oder nen konstruktor verwendet ist egal oder? wegen dem konstruktor ist oo nicht besser und nicht schlechter
Der Konstruktor ist für andere (wesentlich) intuitiver und du selbst brauchst du dir keine Gedanken darüber zu machen, initspieler aufzurufen und hast die Garantie, dass der Zustand von Player immer Sinn macht.
-
Man muss sich IMHO nicht mehr Gedanken machen als ohne... Ein System ausdenken, über das alle Objekte miteinander kommunizieren, muss man sich so oder so.
naja bei prozedural muss ich mir nicht überlegen wie die objekte miteinander kommunizieren ich vergleiche einfach die elemente miteinander
struct object{ int x1,x2,y1,y2; }object1; struct player{int x, y,richtung;}player; void MovePlayer(player* p){ if(p->richtung==LINKS){p->x--;} else if(p->richtung==OBEN){p->y--;} ... if(p->x>object.x1&&p->x<object.x2&&p->y>object.y1&&p->y<object.y2){ //player zurücksetzen da er in object ist } /*hier folgen dann weitere objekte wenn ein neues objekt dazukommt füge ich es hier einfach ein muss mir also nicht überlegen wie die objekte miteinander kommunizieren :)*/ } ... MovePlayer(&player); ...
die vorteile die du über den konstruktor gesagt hast sind zwar ganz nett aber nicht zwindend nötig