OO ist gescheitert

?

Ist OO (definiert nach Alan Key) gescheitert?

  1. JA

  2. NEIN

Das Ergebnis kann erst nach Abgabe einer Stimme betrachtet werden.

Diskutiere OO ist gescheitert im Softwareentwicklung Forum; in dem Thread möchte ich nur zwei Punkte ansprechen, die darlegen warum oo vllt. nicht so sinnvoll ist. Vorab möchte ich definieren, was OO ist...

  1. knotenpunkt
    knotenpunkt Neues Mitglied
    in dem Thread möchte ich nur zwei Punkte ansprechen, die darlegen warum oo vllt. nicht so sinnvoll ist.

    Vorab möchte ich definieren, was OO ist und was es nicht ist:

    OO ist nicht: Polymorphy, Abstraktion, Vererbung, SOLID-Prinzipien,......
    OO ist ein Paradigma wie man ganz generell eine Software aufbauen soll. Sprich in Klassen/Objekten, die sich dann später gegenseitig via Messages unterhalten.
    Dabei ist wichtig, dass Daten und Verhalten gekapselt wird.

    Klassen, die im Namen Service/Manager/Sachbearbeiter etc pp haben sind Prozedurensammlungen, die zwar in sich selbst oobjektorientiert konfiguriert werden können, dann aber auf den DomänenObjekten, also den eigentlichen Daten/Entitäten, prozedural arbeiten. Diese werden in die Services hineingereicht, herausgereicht, herumgereicht, so wie man es eben aus der prozeuduralen Programmierung kennt.

    Viele Programmierprojekte verwenden diese Service-Klassen.
    Ein Indiz dafür ist der Gebrauch der DI-Injektion/Service-Lokatoren.

    Ein objektorientiertes Softwareprojekt würde keine einzige DI-Injektion benötigen.

    Warum aber verwenden viele DI-Injektionen/Service-Klassen.
    Vllt. einfach aus dem Grund, weil OO nichts taugt?!
    Wie seht ihr das?


    Jetzt hätte ich mal noch eine Frage zu einem OO-Aufbau, wie ihr das selbst/anders machen würdet.
    Ich habe eine normale oder aber auch Service Klasse, die wie folgt aussehen könnte.

    Code (Text):
    class Blub
    {
    public T member1;
    public T member2;
    public T member3;

    public T member4

    public Blub(......)
    {
    ....
    }

    public RESULT doSth(T arg1, T arg2)
    {
    // und das ganze macht irgendwas //und verwendet member1-3 sowie arg1-2
    }


    }
    die Probleme, die ich mit dem ganzen hier habe sind die Folgende.

    1:
    nach welchem sinnvollen Algorithmus soll ich entscheiden, dass member1-3 fest in das Objekt gebunden sind und arg1-2 schön dynamisch hineingereicht werden können/dürfen?

    2:
    möchte ich die Methode/Message-Empfänger doSth mit unterschiedlichen member1-3 variablen aufrufen, so habe ich zwei möglichkeiten:
    Ich habe ein Objekt vom Typ Blub und vor jedem doSth Aufruf passe ich member1-3 an.
    Oder ich erstelle N Objekte vom Typ Blub und rufe hier jeweils doSth auf.
    Fühlt sich beides sehr falsch an^^
    Ein BSP:

    Ich habe eine EmailServiceKlasse, die zur Aufgabe hat, DomänenObjekte mit dem Typ EmailNachricht (enthält Absender, Betreff, Empfänger) überreicht zu bekommen und schließlich mit den in dem Service hinterlegten Config-Daten, die Email abzusenden.
    Die DomänenObjekte vom Typ EmailNachricht sind anemic (siehe Fowler), da sie einer c++ Struct ohne nennenswertes Verhalten gleichen. Also ich finde die Structs gut, Fowler findet sie im Kontext der objektorientierung nicht gut.
    Die Service-Klasse EmailServiceKlasse dagen ist in sich selbst schon OO aufgebaut.
    Man kann Sie bspw. mit dem Emailanbieter konfigurieren. Also Domain, Port, Sonstiges.
    Ausserdem erhält die EmailServiceKlasse eine Abhängigkeit LoggerServiceKlasse1 eingespritzt.

    Was ist aber, wenn ich jetzt bspw. zur Laufzeit in Abhängigkeit von Uhrzeit und von der EmailNachricht (Typ EmailNaricht) bestimmen möchte, dass ich LoggerServiceKlasse2 oder LoggerServiceKlasse7 verwenden möchte? Außerdem habe ich 50Emailanbieter und auch das soll genau wie die LoggerServiceKlassen zur Laufzeit und in Abhängigkeit........ entschieden werden.

    Ich glaube Ihr seht das Problem, oder?

    Eine einfache prozedur mit
    Code (Text):

    sendMail(Emailnachricht)
    {
    //hole in Abhängigkeit von time() und Emailnachricht -> LoggerServiceKlasseX
    //hole in Abhängikeit von time() und Emailnachricht ->EmailanbieterX

    sendMail(LoggerServiceKlasseX, EmailanbieterX, Emailnachricht)//überladen

    }
     
    wäre doch viel besser.

    pseudo-OO mit einer weiteren ServiceKlasse könnte dann wie folgt aussehen:

    Code (Text):

    class EmailanbieterANDLoggerServiceDeciderService
    {

    public sendMail(Emailnachricht)
    {
    extrahiere aus Emailnachricht und time() -> LoggerServiceKlasseX und EmailanbieterDataX

    new EmailService(LoggerServiceX, EmailanbieterDataX).sendMail(Emailnachricht);

    }

    }
     
    Nein wir haben nicht den 1. April, aber so wird das teilweise gemacht.
    Den Sinn dahinter verstehe ich nicht^^

    Und jetzt möchte ich noch ein Newsletter an 1Mio User senden.
    Warum soll ich mir 1Mio*(was ich sonst noch an unnötiigen over-head-Klassen habe) sinnlose Objekte auf meinen wertvollen HEAP-Speicher klatschen, nur um eine prozedurale-Funktionalität auszuführen?


    3:
    member4 wird in doSth gar nicht benötigt, in doSthOthers() vllt. dann schon.
    Das ganze Kollidiert auch mit (2:)
    Wenn ich dann ständig
    Code (Text):

    new EmailService(LoggerServiceX, EmailanbieterDataX, null).sendMail(Emailnachricht);
    //wobei null member4 abdeckt
     
    aufurufen muss, dann ist der Mond bereits mit der Erde zu einem Saturn2 fusioniert^^

    Das Single-Responsibilty-Prinzip decke ich am besten in einer Prozedur ab.
    Eine Prozedur benötigt genau exakt die Daten, die es für sich eben benötigt.
    Eine MemberFunktion die den This-Pointer/This-Referenz bekommt, davon aber nur 20% der enthaltenen Daten benötigt, hat nur unnötige Abhängigkeiten.


    Soweit erstmal, ich habe noch einiges mehr, was OO den Nährstoff entziehen würde, aber ich belasse es erstmal dabei.

    Und wie oben bereits geschrieben. Eine Archtitektur mit an Haufen Service-Klassen, die mit anemic-DomänObjekten/Structs arbeiten ist nicht objektorientiert, sondern wie ich es an der Stelle gerne nenne: Pseudo-objektorientiert. Die ServiceKlassen-Landschaft selbst ist objektorientiert. Das Zusammenspiel mit den Daten, mit denen die Landschaft arbeitet dagegen nicht. Zumindest ein Schritt in die richtige Richtung. Wenn jetzt auch die Landschaft selbst wieder proezduraler werden würde -> dann hätten wir endlich wieder eine sehr gute Codequalität, die einerseits performant ist, andererseits aufgrund Ihrer Einfachheit und nicht Overheadheit gut wartbar ist und dritterseits wesentlich schneller zum Erfolg führt.



    lg knotenpunkt
     
  2. Vielleicht hilft dir dieser Kurs hier weiter (Klick!)
  3. mrBrown
    mrBrown Super-Moderator Mitarbeiter
    Kommt drauf an, ob man mehr als nur "Alles ist ein Objekt und die kommunizieren über Messages" für die Beantwortung zulassen will ;)

    Sind halt Design/Entwurfs-Fragen, die kann man eben auch nur auf Design-Ebene klären - und dann landet man bei sowas wie SOLID, High Cohesion, der Domäne...

    Nur mit den oben stehenden Informationen: völlig egal was man macht.


    Die erste Variante ist Unsinn - wäre das nötig, sollten die Dinge Argumente und keinen Felder sein.
    Variante zwei ist völlig Plausibel: wenn member1-3 Teil des Objekts sind, sind's mit unterschiedlichen member1-3 unterschiedliche Objekte, warum sollte ich sie dann nicht neu erzeugen?

    Mit nur so spärlichen Informationen kann man da aber keine fundierte Aussage treffen...

    Hm, einfach für beides einen Proxy.
    Der EmailService braucht davon keine Ahnung zu haben, der ruft einfach die entsprechenden Methoden auf (auf dem Proxy, der das entsprechend weiter delegiert).


    Du kannst dir die nötigen Informationen natürlich auf den noch wertvolleren Stack-Speicher klatschen ;)
    Irgendwo müssen die nötigen Informationen liegen, wie soll man sie sonst versenden?

    Deshalb würde man es auch nicht so machen, eine mögliche Lösung steht weiter oben...

    Das Single-Responsibilty-Prinzip decke ich am besten mit mehreren Klassen/Objekten ab.
    Ein Objekt besteht genau exakt den Daten, die es für sich eben benötigt.
    Einer Prozedur alle nötigen Daten einzeln übergeben, ist doch völliger Unsinn ;)


    Deswegen nutzt man ja auch kein anemic-model, sondern ein vernünftiges Domain-Model. Fowler dazu: "The fundamental horror of this anti-pattern is that it's so contrary to the basic idea of object-oriented design".
    Das ist etwas, was ich gerne Pseudo-Argument nenne :p Ein Argument, was PRO gutem-OO benutzt wird, so verdrehen, dass man das als KONTRA OO nutzen kann.

    Also wieder alles zurück auf Anfang, damit man dann von dort aus von neuem den Vorteil von Objekt-Orientiertem Design sehen kann? ;)
     
  4. knotenpunkt
    knotenpunkt Neues Mitglied
    Hey,

    Ich suche eben eine generische Lösung. Ein statisch aufgebautes starres objekorientiertes Programmgerüst, ist nicht wirklich flexibel und generisch einsetzbar. Das hat zur Folge das es gut testbar ist, aber auch dass man viel Code für wenig Funktionalität schreibt.

    Wenn ich jetzt im Batch-Betrieb doSth aufrufen möchte?
    Die Objektinstanzen sind in dem Fall nur kurzlebig, also eine Art ProzedurenObjekt. new Object() -> parameter als Membervariablen via set-Methoden setzen -> executeMethod aurufen -> Destructor/Garbage Collection.

    Eine direkte Prozedurenaufruf wäre erstens ressourcenschonender und würde nicht soviel Overhead-Code benötigen.

    Warum ist das Unsinn?
    So hast du die Möglichkeit, wirklich alles aus der Prozedur rauszuholen. Bspw. indem du den übergebenen State leicht abändern kannst, nur für die Prozedur.
    Zudem kannst du der Prozedur Structs (c++), associative Arrays (PHP), Java-Objekte ohne Verhalten == structs wie in C/C++ übergeben. Somit übergibst die Variablen auch gesammelt^^. Zudem hast du die Möglichkeit mehrere gesammelte Daten zu übergeben und nicht nur ein Datensammelsatz (this).
    Desweiteren können die Structs bei Bedarf vor der Übergabe angepasst werden.
    Arbeite ich dann nur mit dem Rückgabewert weiter bin ich schon fast bei der funktionalen programmierung angelagant. Mit einem Sideffekt bin ich dann bei der prozeduralen Programmierung.

    Aber warum ist das nicht sinnvoll?

    Könntest du eventuell ein Beispiel posten. Kann mir nicht ganz vorstellen was du meinst.
    Aber ich denke es fällt auch hier ein prozedural aufgebautes Programm heraus.

    Ist denke so bin ich ressourcenschonender und zweitens auch flexibler.
    Du kannst die Programmstruktur auch für Third-Party APIs gut einsetzen, wo du die Daten nicht selbst im Speicher hälst. Auch passt das ganze perfekt zu relationelen Datenbanken, wo du die Datenänderungen direkt auf/in der Datenbank durchführst.

    Was würde man so nicht machen?

    Wie sieht ein vernünftiges und vor allem flexibles und dynamisch einsetzbares domain-model aus?
    Du hast noch nichts zu meinen oben genannten Services und DI-Injection/Service-Locatoren gesagt.
    In einem vernünftigen Domain-Model kommen diese nicht vor, würdest du das bestätigen?
    Wenn aber keine proezdurale Service-Klassen existieren, wie erreichst du dann ein dynamisches Programm? auf der Grundlage von einer starren/unflexiblen Objektwelt?
    Ich denke die Paradoxie erkennt man^^

    Ein Beispiel, was ich dafür immer gerne hernehme:

    Du möchtest eine UserBan-Funktionalität implementieren.
    Es macht null Sinn, die Banfunktionalität in die Klasse eines Users/Admin hineinzuimplementieren.
    Also benötige ich hier sozusagen einen BanService, etwas aussenstehendes

    diesem BanService wird jetzt folgendes übergeben. der User der bannen möchte, der User der gebannt werden soll, die Uhrzeit und vieles weitere (eventuell holt sich die Funktion die Daten auch selbst, da noch zu Beginn nicht ganz klar ist, welche Daten die Funktion letzten Endes benötigt)

    Gehen wir davon aus der bannende User hat die abstrakte Adminberechtigung 5
    Alle Admins mit dem Status 5 dürfen nur zwischen 17 und 18Uhr bannen.

    Außerdem gibt der Admin eine Ban-Zeit zwischen 1-10 an.

    Wählt der Admin die 4 und hat davor schon 3User gebannt, die älter als 70Jahre sind und eine weitere Person die sich erst vor 3Tagen registriert hat, dann beträgt bei der Nummer vier die Ban-Zeit der aktuellen Person 9 Tage. Außerdem, sollte die zu bannende Person bereits über 6Monate registriert sein, wird diese via Email über den Ban benachrichtigt. Je nach Flags, die der Admin setzt, kann die Emailbenachrichtigung unterdrückt und falls nicht, im Detail angepasst werden.

    usw. usf.

    Warum das ganze nicht in die UserAdmin-Klasse?
    Vllt. möchte das System selbst ohne zutun eines Admins selbst auch User bannen können, aufgrund irgendwelcher Kriterien.


    Was ich damit verdeutlichen möchte: Das ganze geht doch nur sinnvoll in einer Prozedur bzw. divide-and-conquer Prozedurlandschaft.
    Wie möchtest du das sinnvoll objektorientiert machen?


    Zurück auf ein Level, das gut funktioniert.
    Man sollte nicht OO Programmieren des OO zu Willen.

    Und warum verwenden soviele Programmierer Services/etc pp?
    Services sind prozedural!


    lg knotenpunkt
     
  5. mrBrown
    mrBrown Super-Moderator Mitarbeiter
    Häh? ich habe keine Ahnung, was das mit Objektorientiert vs Prozedual zu tun hat...

    Objektorientiert != Garbagecollector != Resourcen-Verschwendend != Overhead-Code.

    Nach dem Kompilieren kann aus "new Object() -> parameter als Membervariablen via set-Methoden setzen -> executeMethod aurufen -> Destructor/Garbage Collection." durchaus ein "executeMethod aurufen" geworden sein, genauso wie das bei deiner Variante der Fall wäre.

    Ressourcenschonender ist dann nichts mehr, es bleibt der "Overhead-Code" (solange du das "mehr" an nötigem Source-Code meinst), der von den wenigstens als "Overhead" angesehen wird, sondern einfach als sinnvolle Struktur.


    Und bringe ich dann die Funktion noch mit in dem Objekt unter, sodass ich die Funktion und die dazu gehörenden Daten zusammen habe, bin ich bei Objektorientiert und wir drehen uns im Kreis.
    Und Vermeide ich dann Seiteneffekte, bin ich bei Objektorientiert und Funktional (siehe Scala).

    Wenn du Objekte bei Objektorientierter Programmierung als "Datensammelsatz" ansiehst, hast du Objektorientierte Programmierung nicht verstanden - dann ist es natürlich besser, keine Objektorientierte Programmierung zu nutzen.


    Wenn du über Objektorientierte Programmierung urteilen willst, sollte dir doch zumindest das Proxy-Pattern geläufig sein?

    Code (Text):

    class MailService{
      sendMail(Mail mail) {
        mailLogger.log(mail);
        mailServer.send(mail);
      }
    }
    interface  MailLogger {
      log(Mail mail);
    }
    class MailLoggerProxy implements MailLogger {
     log(Mail mail) {
       MailLogger logger  = getLoggerForMail(mail);
        logger.log(mail);
      }

      getLoggerForMail(Mail mail) {
        //die von dir nicht gezeigte Magie...
      }
    }
    class SimpleMailLogger implements MailLogger {
     log(Mail mail) {
       sout(mail.sender);
      }
    }
     
    Aber wie erreichst du denn bei deinem rein prozeduralem Programm zB die Auswahl zwischen unterschiedlichen Mail-Servern, die auf unterschiedliche Arten und Weisen benutzt werden müssen? Und wie kann man da dynamisch zur Laufzeit neue hinzufügen?


    Inwiefern sind Daten auf dem Stack resourcenschonender und flexibler als auf dem Heap? (wobei Objektorientiert natürlich nicht voraussetzt, das Daten überhaupt auf dem Heap liegen, da vermischt du wieder eine Mögliche Implementierung mit einem Konzept)
    Und wie bringst du überhaupt 1 Mio. Mails auf dem Stack unter?

    Wo die Daten herkommen ist völlig egal, ich kann durchaus auch Objektorientiert mit denen arbeiten, wenn die in einer Relationen Datenbank liegen.
    Wie passt deine Lösung eigentlich zu Objektorientierten Datenbanken? ;)


    Das, was ich zitiert hab?

    Genauso, wie die eine "vernünftige und vor allem flexible und dynamisch einsetzbare" Prozedur aussieht: nicht existent.

    Ein Domänen-Modell ist nur ein Modell für *eine* Domäne, wie soll sowas dynamisch und flexibel aussehen?
    Weder kommen Service-Klassen in einem Domänen-Model niemals vor, noch sind diese zwingend nötig. (Der Begriff "Service" ist btw. hauptsächlich durch Domain-Driven-Design geprägt.)

    Ich habe keine Ahnung, was du unter einem "dynamischen Programm" verstehst, aber generell und nach deiner Definition von OO erreicht man das, indem Objekte sich Nachrichten schicken.

    DI ist aber ein generelles Konzept, und hat nicht mit Services zu tun.
    Es ist nichts weiter, als dass Objekte ihre Abhängigkeiten übergeben bekommen, anstatt sie sich selbst zu besorgen. Über die Abhängigkeiten sagt das nichts aus.


    Dein Argument ist: Sobald irgendwo eine Funktion existiert, ist das ganze Prozedural und absolut nicht mehr Objekt-Orientiert?

    Wie würdest du das ganze denn, ohne jegliche Objekt-Orientierung, umsetzen? Ellenlange Methoden mit zig verschachtelten if's?


    Man programmiert nicht OO, um OO zu programmieren, sondern weil es für die meisten Dinge gut Funktioniert. OO gibt es nicht ohne Grund.

    Und das Methoden in Services Prozedural sind (ich gehe mal davon aus, dass das nach deiner Definition von Prozedural so ist), bedeutet für dich, dass sie nicht mehr Objektorientiert sind?
     
    Zuletzt bearbeitet: 16. Mai 2018
  6. AndiE
    AndiE Mitglied
    Als "Halb-Laie" finde ich den Titel sehr provokativ, und auch der Entscheidung, was OOP ist und was nicht, kann ich nicht zustimmen.
    Aus meiner "C"-Zeit kenne ich das so, dass Maschinencode (Mnemotics) in Prozeduren zusammengefaßt wurden, und es dann Header-Dateien mit den Signaturen gab und Compilierte Bibliotheken. Das Programm selbst besteht dann wieder das Prozeduren, die Porzeduren aufrufen, wobei mit der "main()"-Prozedur begonnen wird. In diesem Umfeld, dass ich als "prozedural" bezeichnen würde, gibt es dann als komplexisten Typen die "struct", die mehrere Daten verschiedener Typen zusammenfasst.
    Der objektorientierte Ansatz, wie wir ihn aus dem MVC- oder dem 3-Schichten-Modell kennen, erzeugt Datenobjekte, die miteinander kommunizieren. Dabei kann man eben zwischen der statischen und der dynamischen Sicht unterscheiden. Bei einem Taschenrechner gibt es eine Klasse, die die Darstellung übernimmt und Nutzereingaben entgegennimmt. Bei einer Nutzereingabe ruft sie eine Methode des Controllers auf, der wiederum eine Methode des Datenobjektes aufruft. So würde ich das organisieren, auch wenn es hier im Forum gerne anders gemacht wird. Der Vorteil ist eben, dass ich als Bearbeiter mich nicht erst umständlich in das reindenken muss, was der andere programmiert hat.Wer schon mal den Hüpfweg in einem prozeduralen Programm nachvollzogen hat, weiß was ich meine. Bei einer CD-Verwaltung etc. kann ich die vorhandene Struktur im Datenmodell realitätsnah abbilden. Ich habe ein Regal->ich bilde das mit einer List-Klasse ab. In dem Regal sind CD->Datenobjekte.

    Ich finde, dass Scriptsprachen dazu verleiten, dieses Paradigma zu umgehen, was dann zu "IOP-indirekt objektorientierter Programmierung" führt, ein Begriff, der mir im Zusammenhang mit "Perl" aufgefallen ist. Dabei benutzt man die Methoden der "vorgefertigten" Klassen, und das Programm selbst kommt ohne Klassendefinition und Methodendeklaration aus.
     
  7. knotenpunkt
    knotenpunkt Neues Mitglied
    Es soll einen negativen Gesichtspunkt von OO hervorheben und gleichzeitig darauf hinweisen, dass Prozedurale Programmierung diese Schwäche nicht hat.


    Es kann?!...... Ja die Compiler optimieren schon ganz gut, wobei ob das hier wegoptimiert wird, das ist so die Frage^^
    Aber es fühlt sich halt einfach schlecht an, "schlechten" Code zu schreiben, auch wenn der Compiler das nacher wegoptimieren würde. Warum nicht gleich straightforward programmieren?
    Ja ich meine mit Overhead auch den Source-Code.
    Warum soll diese Struktur, die du meinst, sinnvoller sein?
    Es sieht vllt. ästhetisch aus, mehr aber auch nicht. Und wenn man dann noch weiß, dass dies wegoptimiert werden muss, dass es performt, dann sehe ich darin auch keine Ästhetik mehr^^


    Diese Seiteneffekte sind unter Umständen ja gewollt. Ok vermutlich nicht für denjenigen, der den Code dann testen soll. Aber sinnvoll strukturiert, kann man auch beherrschbaren prozeduralen Code schreiben.

    Möchte ich Funktionen und Daten zusammen in ein Objekt bringen, dann bedingt das ganze auch, dass die Daten vor Ort sind. So sind direkte Datenmanipulationen direkt auf der Datenbank bspw. ausgeschlossen.
    Zudem, wann arbeitet eine Objektmethode auch nur auf den Daten, die sie selbst bereithält?
    Es gibt einen Fall, wo das so ist: ADTs und einfachste Datentypen......... but that was it.

    Folgende Probleme tauchen bei komplexeren Datenstrukturen auf.
    Erstens möchte ich nicht lange Graphoperationen durchführen um an irgend ein Objekt/Datensatz im letzten Zweig des grossen Urwalds zu kommen und zweitens möchte ich vllt. auch gar keinen Graphen haben, sondern schön losgekoppelte Objekte/Daten.

    Zum Thema "OOP als \"Datensammelsatz\"":
    Nein ich sehe das nicht so. Aber genau weil ich das nicht so sehe, sehe ich OO als gescheitert an^^
    Wann macht es deiner Meinung nach Sinn Funktionen an die Daten zu knüpfen.
    Meiner Meinung nach - wie oben geschrieben - bei ADTS (Listen,.....) und einfachsten Datentypen (boolean, int) (also Datentypen, wo die Funktionen auch wirklich nur auf dem Datentyp arbeitet).

    Ich kenne sogar alle GoF-Patterns und weitere + Architekturpatterns

    Die liegen alle vor: Als Datensatz direkt im Programmcode oder auch in der Datenbank.
    Das witzige an deinem Codebeispiel ist eben, dass es meiner Meinung nach prozedural arbeitet.

    Dein Mailserver (1Funktion -> 1Prozedur) ruft weitere Subprozeduren (-> loggger und sendMail).
    Diese sind eben in weiteren Prozedurenklassen hinterlegt.
    Ich sehe hier keinen Vorteil.
    Welchen Vorteil siehst du darin?...... Das sind weitestgehend stateless Prozedurenklassen, die keiner Klasse bedürften.

    Aber auch ein anderers Problem sehe ich hier. Ein Problem, das ich auch ganz generell in der prozeduralen Programmierung habe, wenn ich den Code auf verschiedene Funktionen aufteile, wenn auch nicht ganz so drastisch.

    Gehen wir mal davon aus, zur Bestimmung des Log-Services, aber auch zur Bestimmung des Emailanbieters wird ein ähnlicher Code ausgeführt. Was ich meine ist das. Ein berechnetes Zwischenergebnis beim Finden des LogServices kann dazu hergenommen werden, den Emailanbieter zu bestimmen. Trenne ich das so strikt, wie du es gemacht hast, so kann ich ein temporär berechnetes Zwischenergebnis dafür nicht hernehmen. Und das kann ganz sicher kein Compiler wegoptimieren.

    prozedural würde ich das dann so ähnlich machen. sendMail(mailData) -> calculate LogService(mailData)
    aus dem LogService kommen jetzt zwei Datensäze zurück, einerseits der LogService an sich und zweitens irgend ein beschleunigendes Zwischenergebnis tmpData

    Also rufe ich jetzt ne prozedur auf, die wie folgt heisst: ->calculate Emailanbieter (mailData, tmpData)
    Im Falle dessen, dass mir tmpData nicht zur Verfügung steht, weil ich bspw. auf den LogService verzichtet habe, schreibe ich natürlich auch noch einfach ein calculateEmailanbieter(struct mailData) Prozedur

    Wie würdest du das objektorientierisieren?
    Und warum würdest du das überhaupt mit 5 veschiedenen Klassen machen, wenn es doch auch straightforward geht, in java also mit static functionen.

    Und wie gehst du an die Sache heran, wenn du es Top-Bottom oder Bottom-Up aufbaust?
    Wie sind deine Gedankengänge, das direkt von Anfang an richtig zu machen?



    Ja in C++ kann ich sie mir auch auf den Stack oder sonst wohin packen. War wirklich etwas falsch von mir formuliert.

    Wenn die Daten in der Datenbank liegen, dann kann ich sie erstmal durch umständliche OR-Mapper oder händisch in meinen Speicher holen und dabei schön nen Graphen aufbauen und dann damit arbeiten -> das finde ich nicht ressourcenschonend.

    Andererseits kann ich wieder meine prozeduren/Service-Klassen verwenden, die dann direkt mit der DatenbankAPI kommunizieren....... Das ist meiner Meinung nach sinnvoll, da ich mir hier vor allem schnell arbeitende Datenbanken zu Nutze machen kann.

    Die Problemstellung war die, dass unter Umständen unnötige Abhängikeiten in der Doing/prozeduren/Service-Klasse habe, die für bestimmte Methodenaurufe irrelevant sind und somit störend!

    Das musste mir etwas näher erklären^^


    Nach Fowler sollten sie auch nicht vorkommen. Und ich sehe das genau wie Fowler, objektorientierung besteht nicht aus service-Klasssen. Der Einsatz dieser Klassen macht das ganze wieder prozedural mit oo-ästhetik. Nur dass es dann icht vielleicht sogar besser wäre auf diese Ästhetik zu verzichten und direkt prozedural (das schließt eine Modualisierung nicht aus!) zu programmieren.

    Ja Objekte schicken sich Nachrichten, aber was steht deiner Meinung nach in diesen Narchrichten drinnen.
    In deiner MailService Klasse wird ein MailObjekt/Struct geschickt........... prozeduren schicken sich auch derartige Nachrichten. Wie sollen sich die Nachrichten bei ordentlicher oo-programmierung unterscheiden?

    Was ich vor allem als undynamisch ansehe ist das folgende:
    Die festverdrahteten Objekte. Die Membervariablen, die fest verdrahtet auf andere Objekte zeigen.
    Somit habe ich eine Möglichkeit um an diese Informationen zu kommen, aus der Sichtweise einer Prozedur oder Service-Klasse:

    Ich muss mich mich im Graph entlang hangeln bis ich an entsprechender Information bin, die aber in sich dann ein anemic Objekt darstellt.

    ein Datenbanksystem dagegen kann das viel effizienter und ich komme direkt an die Information.

    Wenn ich jetzt aus den Anemic-Objekten richtige Objekte mache, sprich funktionalität dazuimplementiere, dann arbeitet die funktionalität auf THIS, also auf den Daten des Objekts selbst. Und das macht das ganze unflexibel, da ich ja nur auf den THIS Daten arbeiten darf/kann.
    Also werden unabhängige Serviceklassen/prozeduren eingeführt um in die ganze Bude wieder etwas Schwung/dynamic zu bringen^^


    Divide-And-Conquer...... also viele Methoden/Funktionen.
    Switch-Cases finde ich gar nicht so problematisch. Aber wenn es sein muss, kann man auch schön polymorphe Funktionspointer einsetzen^^
    Zum Thema "wenn irgendwo eine Funktion existiert": Ja das ist ein Schritt weg von OO. Nicht gänzlich, aber kein reines OO mehr. Je mehr -> desto mehr pseudo-oo wird es^^

    Warum und für was funktioniert es gut?

    Ja es ist nicht mehr objektorientiert.
    Und die Frage, die ich mir stelle, warum dann überhaupt Service-Klassen und nicht direkt Service-prozeduren.
    Auch diese kann man konfigurieren.
    Aber das ist nicht das Hauptthema.
    Das Hauptthema ist die Frage, warum verwenden soviele Programmierer, wenn Sie meinen OO zu programmieren, ServiceKlassen.
    Meiner Meinung nach, weil Sie das reine OO nicht akzeptieren und das somit ein klares Indiz, dass es gescheitert ist.


    @AndiE

    Gegen Datenmodellierung habe ich nichts.
    Mich stört es nur Funktionalität und Daten zusammenzupacken.
    Und anscheinend stört das nicht nur mich, sondern viele andere auch -> Lösung, wenn auch nur bedingt sinnvoll: Serviceklassen.
    Das andere was du ansprichst, sind Architekturentscheidungen, die erstmal nichts mit OO zu tun haben.
    ich kann auch MVC ohne Klassen und Objekte programmieren^^
    Das ist nur ne Frage der Modularisierung/Strukturierens.

    OO ist eine Frage des ProgrammierDenkens.

    MVC lässt sich sowohl im oo-denken als auch im pp-denken umsetzen.

    Und wenn du die einzelnen patterns aus mvc herausarbeiten möchtest, bspw. strategy und observer, dann geht das sehr gut mit prozeduralem Denken. Wie ich oben geschrieben habe, kannst du ja für die polymorphie (auf polymorphie bauen die ganzen DesignPatterns ja auf) Funktionspointer verwenden, oder auch switch-cases, die super schnell sind.

    in C++ sollte man wo es nur geht auf vtables verzichten.


    Ja gut soweit


    lg knotenpunkt
     
  8. Meniskusschaden
    Meniskusschaden Bekanntes Mitglied
    Das ist eben der gängige Weg, objektorientiertes Design umzusetzen, wenn man nur eine prozedurale Sprache hat. Ist wohl eher ein Argument pro OO.
     
  9. mrBrown
    mrBrown Super-Moderator Mitarbeiter
    Du kannst also rein prozedural ein "flexibel und generisch einsetzbares Programmgerüst" schreiben?


    Für mich fühlt es sich besser an, klaren und verständlichen Code zu schreiben, anstatt hochoptimierten...

    "ästhetisch aussehen" im Sinne von "klar, verständlich, strukturiert, etc" (was Lesbarkeit, Wartbarkeit und Testbarkeit impliziert) ist zumindest mir deutlich wichtiger als performant und Maschinennah...


    Nö, eigentlich ist das in den meisten vernünftigen, Domänenorientierten Entwürfen der Fall.


    Beides kannst du mit vernünftigem Design verhindern.

    Viellicht solltest du dich mal tiefergehend mit Objekt-Orientiertem Design beschäftigen? Grundlektüre wäre da Domain Driven Design.

    Na gut, ich seh's ein: wenn man geschachtelte Objekte, die über Messages kommunizieren, als prozedural bezeichnet, programmieren alle prozedural.

    Nur so als Frage: was ist für dich Objektorientiert, wenn es über Messages kommunizierende Objekte nicht sind?


    In dem Fall, gibt es eben ein Objekte, was als Cache für das Zwischenergebnis fungiert, oder die Mail selbst kann das zurückgeben und cacht es entsprechend, alles kein Hexenwerk...

    gibt zig Varianten, ohne die genauen Anforderungen zu kennen, kann man da keine von Anfang an richtige Lösung liefern - genausowenig bei der Prozeduralen Variante.

    Warum ich das mit 5 Klassen machen würde?
    Weil 5 Klassen, die jeweils für genau ein Ding zuständig sind, deutlich einfacher sind, als 17 Prozeduren, die jeweils 32 Dinge tun.
    Prozedural habe ich immer eine extreme Bindung von allen Dingen, was das ganze extrem starr und unflexibel macht. (Um mal auf Alan Key zurückzukommen: spätes Binden ist einer der wesentlichen Punkte von OO, wenn OO gescheitert ist, dürfe spätes Binden ja auch schlecht sein?)


    Und wo packst du die zum Versenden nötigen Daten jetzt hin, damit sie weniger Platz als in der OO-Variante brauchen? Oder übernimmt dann die DB das verschicken, und deine Anwendung benutzt die Daten gar nicht? o_O

    Du wirst immer Fälle finden, für die irgendwas ungeeignet ist...

    Wenn ich keinerlei Objekte brauche und auch keinerlei Business-Logik in diesen habe, dann nutz ich halt auch keine Objekt-Orientierte Sprache.
    Wenn du natürlich nicht zueinander passende Sprache und Anforderungen wählst, sind solche Probleme klar...

    Du forderst: "vernünftiges und vor allem flexibles und dynamisch einsetzbares domain-model"

    Definier doch mal bitte, was deiner Meinung nach ein eben dieses ist?

    Ein domain-model ist für eine spezifische Problemdomäne da - was muss da für dich flexibles und dynamisch sein?

    Ein Service-Layer, welches die gesamte Business-Logik enthält, hat nichts mit OO zu tun - und eben das kritisiert Fowler!
    Ein Service, ohne "-Layer", nach DDD, gehört durchaus zur Problemdomäne, auch bei Fowler. Leseempfehlung (von Fowler): Domain Driven Design.

    Aus "ein kleiner Teil des Objekt-Orientierten Designs ist prozedural" ist für mich auch noch kein "besser ganz auf OO verzichten"...

    Um mich selbst zu zitieren: "wenn man geschachtelte Objekte, die über Messages kommunizieren, als prozedural bezeichnet, programmieren alle prozedural."

    Wenn für dich OO == Prozedural ist, warum führen wir dieses Gespräch eigentlich?

    Gute Erkenntnis: schlecht umgesetztes OO ist schlecht. Herzlichen Glückwunsch dazu.

    Sind die Argumente eigentlich bewusst nicht für sinnvolles OO zutreffend, sondern nur für Objekte als Datencontainer, die man bei Prozeduraler Programmierung üblicherweise nutzt?
    *Dabei* musst du dich durch die Daten hangeln - mit OO dagegen kannst du es anders lösen (und machst das bei vernünftigem OO auch).


    Und eine Prozedur kann nur auf den ihr übergebenen Daten arbeiten, ist Prozedual jetzt etwa noch stärker eingeschränkt?

    Das Objekte mit sich selbst arbeiten, habe ich bisher weder als Einschränkung noch als Unflexibel empfunden...
    Ganz im Gegenteil, eine Einschränkung ist doch völlig nötig. Wie soll denn ein Entwurf, bei dem alles Zugriff auf alles hat, in irgendwer Art und Weise überschaubar bleiben?

    Deine Meinung, von der dich auch niemand abbringen können wird.

    Meine Meinung: Prozedural ist gescheitert, weil die meisten Leute OO oder Funktional programmieren.
     
  10. mrBrown
    mrBrown Super-Moderator Mitarbeiter
    Du kannst also rein prozedural ein "flexibel und generisch einsetzbares Programmgerüst" schreiben?


    Für mich fühlt es sich besser an, klaren und verständlichen Code zu schreiben, anstatt hochoptimierten...

    "ästhetisch aussehen" im Sinne von "klar, verständlich, strukturiert, etc" (was Lesbarkeit, Wartbarkeit und Testbarkeit impliziert) ist zumindest mir deutlich wichtiger als performant und Maschinennah...


    Nö, eigentlich ist das in den meisten vernünftigen, Domänenorientierten Entwürfen der Fall.


    Beides kannst du mit vernünftigem Design verhindern.

    Viellicht solltest du dich mal tiefergehend mit Objekt-Orientiertem Design beschäftigen? Grundlektüre wäre da Domain Driven Design.

    Na gut, ich seh's ein: wenn man geschachtelte Objekte, die über Messages kommunizieren, als prozedural bezeichnet, programmieren alle prozedural.

    Nur so als Frage: was ist für dich Objektorientiert, wenn es über Messages kommunizierende Objekte nicht sind?


    In dem Fall, gibt es eben ein Objekte, was als Cache für das Zwischenergebnis fungiert, oder die Mail selbst kann das zurückgeben und cacht es entsprechend, alles kein Hexenwerk...

    gibt zig Varianten, ohne die genauen Anforderungen zu kennen, kann man da keine von Anfang an richtige Lösung liefern - genausowenig bei der Prozeduralen Variante.

    Warum ich das mit 5 Klassen machen würde?
    Weil 5 Klassen, die jeweils für genau ein Ding zuständig sind, deutlich einfacher sind, als 17 Prozeduren, die jeweils 32 Dinge tun.
    Prozedural habe ich immer eine extreme Bindung von allen Dingen, was das ganze extrem starr und unflexibel macht. (Um mal auf Alan Key zurückzukommen: spätes Binden ist einer der wesentlichen Punkte von OO, wenn OO gescheitert ist, dürfe spätes Binden ja auch schlecht sein?)


    Und wo packst du die zum Versenden nötigen Daten jetzt hin, damit sie weniger Platz als in der OO-Variante brauchen? Oder übernimmt dann die DB das verschicken, und deine Anwendung benutzt die Daten gar nicht? o_O

    Du wirst immer Fälle finden, für die irgendwas ungeeignet ist...

    Wenn ich keinerlei Objekte brauche und auch keinerlei Business-Logik in diesen habe, dann nutz ich halt auch keine Objekt-Orientierte Sprache.
    Wenn du natürlich nicht zueinander passende Sprache und Anforderungen wählst, sind solche Probleme klar...

    Du forderst: "vernünftiges und vor allem flexibles und dynamisch einsetzbares domain-model"

    Definier doch mal bitte, was deiner Meinung nach ein eben dieses ist?

    Ein domain-model ist für eine spezifische Problemdomäne da - was muss da für dich flexibles und dynamisch sein?

    Ein Service-Layer, welches die gesamte Business-Logik enthält, hat nichts mit OO zu tun - und eben das kritisiert Fowler!
    Ein Service, ohne "-Layer", nach DDD, ist aber eben nicht zu ersetzen und gehört durchaus zur Problemdomäne. Leseempfehlung (von Fowler): Domain Driven Design.

    Aus "ein kleiner Teil des Objekt-Orientierten Designs ist prozedural" ist für mich auch noch kein "besser ganz auf OO verzichten"...

    Um mich selbst zu zitieren: "wenn man geschachtelte Objekte, die über Messages kommunizieren, als prozedural bezeichnet, programmieren alle prozedural."

    Wenn für dich OO == Prozedural ist, warum führen wir dieses Gespräch eigentlich?

    Gute Erkenntnis: schlecht umgesetztes OO ist schlecht. Herzlichen Glückwunsch dazu.

    Sind die Argumente eigentlich bewusst nicht für sinnvolles OO zutreffend, sondern nur für Objekte als Datencontainer, die man bei Prozeduraler Programmierung üblicherweise nutzt?
    *Dabei* musst du dich durch die Daten hangeln - mit OO dagegen kannst du es anders lösen (und machst das bei vernünftigem OO auch).


    Und eine Prozedur kann nur auf den ihr übergebenen Daten arbeiten, ist Prozedual jetzt etwa noch stärker eingeschränkt?

    Das Objekte mit sich selbst arbeiten, habe ich bisher weder als Einschränkung noch als Unflexibel empfunden...
    Ganz im Gegenteil, eine Einschränkung ist doch völlig nötig. Wie soll denn ein Entwurf, bei dem alles Zugriff auf alles hat, in irgendwer Art und Weise überschaubar bleiben?

    Deine Meinung, von der dich auch niemand abbringen können wird.

    Meine Meinung: Prozedural ist gescheitert, weil die meisten Leute OO oder Funktional programmieren.
     
  11. mrBrown
    mrBrown Super-Moderator Mitarbeiter
    Nur mal so als Beispielproblemstellung:

    Es soll Konten geben, die einen Kontostand haben (Ganzzahlig reicht). Man kann den Kontostand erhöhen und verringern (um ganzzahlige Werte), er darf aber nie negativ sein.
    Wie bildest du das Prozedural ab?
     

Die Seite wird geladen...

OO ist gescheitert - Ähnliche Themen

Weihnachtsbaum implementieren gescheitert.
Weihnachtsbaum implementieren gescheitert. im Forum Java Basics - Anfänger-Themen
Tannenbaum implementieren gescheitert
Tannenbaum implementieren gescheitert im Forum Java Basics - Anfänger-Themen
Code auf Klasse verlegen - Mission gescheitert
Code auf Klasse verlegen - Mission gescheitert im Forum Java Basics - Anfänger-Themen
Gescheiterte Projekte bzw. Konsequenzen
Gescheiterte Projekte bzw. Konsequenzen im Forum Plauderecke
Thema: OO ist gescheitert