Login
Newsletter
Werbung

Thema: Objektorientierte Programmierung: Teil 1 – OOP in der Praxis

26 Kommentar(e) || Alle anzeigen ||  RSS
Kommentare von Lesern spiegeln nicht unbedingt die Meinung der Redaktion wider.
0
Von nachbarnebenan am Do, 12. April 2012 um 15:25 #

Eine einfachere Variante ist es, nicht verschiedene Bots für verschiedene Strategien zu schreiben, sondern die Strategie selbst in einer Klasse zu kapseln und dem Konstructor des Bot eine konkrete Instanz zu übergeben, die er verwenden soll. Damit ließe sich die Strategie sogar während des Spiels wechseln bzw. abfragen oder ihre Parameter ändern. Ich meine — was interessiert die Klasse Bot, wie die Strategie zu ihren Entscheidungen kommt? Die Methode decide bekommt einfach das aktuelle Gebot und liefert bool zurück. Die vergangene Liste kann dann intern gespeichert werden oder nicht.
Das gleiche mit Spieler und Bot, beide könnten als Spezialisierungen einer allgemeinen Klasse Mitspieler angesehen werden. Das Spiel bekommt zwei Instanzen dieser Klassen und dann spielen eben auch mal zwei Bots oder zwei Spieler gegeneinander, am Prinzip ändert sich dabei nichts.

[
| Versenden | Drucken ]
  • 0
    Von Bolitho am Do, 12. April 2012 um 15:29 #

    :up: Das sehe ich genau so!

    Man könnte sogar an Metastrategien denken, die die "richtige" zur Laufzeit wechseln bzw. kombinieren.

    [
    | Versenden | Drucken ]
    0
    Von cs am Do, 12. April 2012 um 16:34 #

    Wenn man das ganze weiter treibt, kann man fast alle Eigenschaften der Bots über solche dynamisch hinzufügbaren Komponenten realisieren (Position, Physik, KI, aber auch andere Ressourcen, die mit dem Bot verknüpft sind). Das ganze nennt sich dann CBSE (Component Based Software Engineering) und wird gerade in Computerspielen sehr gerne verwendet um allen Spiel-Entitäten komplexe Eigenschaftskombinationen zuzuweisen, ohne auf umständliche und starre Objekthierarchien wie bei OOP angewiesen zu sein.

    [
    | Versenden | Drucken ]
    0
    Von Kurt K am Do, 12. April 2012 um 17:51 #

    Das wäre dann das berühmte Strategy-Pattern.

    Für eine lose Kopplung würde sich dann als Verbesserung der Einsatz eines IoC-Frameworks empfehlen. Ist ja derzeit der letzte Schrei.

    [
    | Versenden | Drucken ]
    • 0
      Von alexThunder am Do, 12. April 2012 um 23:58 #

      Mit den IoC-Frameworks wäre ich sehr vorsichtig!

      Bei größeren Projekten kann das ganz schnell dazu führen, dass der Code unverständlich wird, wenn die Konfigurationen verstreut sind (geht schneller, als man denkt). Außerdem kann es sein, dass man (zur Laufzeit) in verschiedenen Komponenten unterschiedliche Abhängigkeiten braucht. Holt man sich dann die Abhängigkeiten über das Ändern der Konfiguration, kriegen evtl. die anderen Komponenten nicht mehr die Abhängigkeiten, die sie eig. haben sollten. Die Lösung wäre, die Konfigurationen selber wieder zu entkoppeln, was aber auf das ursprüngliche Problem (dass so ein Framwork eig. lösen sollte) hinausläuft. Vor dem steht man dann wieder und hat dazu noch Overhead (durch das Framework).

      Um das Problem deutlicher zu machen, überspitz ichs mal:

      Das obige Problem ließe sich lösen, wenn man für die entsprechenden Zweige im Code einfach unterschiedliche Konfigurationen einführt. Es kann aber sein, dass ein paar Abhängigkeiten in allen Konfigs gleich sind und auch gleich sein sollen. Tatsächlich hat man dann Abhängigkeiten unter den Konfigs. (ob nur logisch, oder direkt im Code ist egal). Um diese zu Verwalten könnte man wieder das Framework verwenden und schwupps hat man das Problem dupliziert, anstatt es zu lösen. Theoretisch kann man das beliebig oft machen, bis man tatsächlich mal das eig. Problem gelöst hat.

      Falls dann mal jemand neues sich mit dem Code befassen soll, wird der einige Nächte nicht mehr ruhig schlafen können.

      Man sollte, wenn überhaupt, solche Frameworks wirklich nur mit oberster Vorsicht verwenden und den Einsatz gut durchplanen. Meiner Meinung nach kann man dann auch gleich das Projekt besser planen und den Einsatz solcher Frameworks vermeiden. Halbwegs gute Sprachen bieten ja auf Sprachebene genug Möglichkeiten, z.B. Entwurfsmuster wie aus GoF da einzusetzen, wo sie Sinn machen.

      Achja :D
      Zum ursprünglichen Post: Strategy wäre jetzt auch meine Wahl gewesen :)

      Dieser Beitrag wurde 1 mal editiert. Zuletzt am 13. Apr 2012 um 00:18.
      [
      | Versenden | Drucken ]
    0
    Von jo am Fr, 13. April 2012 um 00:54 #

    hat einen Namen. Nennt sich Dependency Injection.

    [
    | Versenden | Drucken ]
0
Von Bolitho am Do, 12. April 2012 um 15:36 #

Imho ist das ganze Thema schwer von einer Sprache zu trennen; zumindest von einer Klasse von Sprachen. Implizit wird das durch Voraussetzungen a la "Klassen", "UML" usw. schon gemacht, aber man hätte da doch gerne mal die gängigen Sprachen nennen können, für die der Artikel geeignet ist (Java, C#, C++, ...).

Imho sind das vor allem Sprachen, die den stark Klassen zentrierten Ansatz bei OOP verfolgen. JavaScript fiele hier komplett durchs Raster, SmallTalk entsprechend auch uvm. Selbst für Sprachen wie Python oder Ruby ist das teilweise nur schwer anwendbar, gibt es bei diesen durchaus andere, sinnvollere Mechanismen, Dinge umzusetzen, die hier alleine über Klassen gelöst werden.

Ein vermeindlich allgemein gehaltener Artikel wird so imho derart speziell, dass der Anspruch in keinem Verhältnis zum Inhalt steht.

[
| Versenden | Drucken ]
  • 0
    Von t-bot am Do, 12. April 2012 um 16:11 #

    Hi,

    > Imho sind das vor allem Sprachen, die den stark Klassen zentrierten Ansatz bei
    > OOP verfolgen. JavaScript fiele hier komplett durchs Raster, SmallTalk
    > entsprechend auch uvm.

    inwiefern fiele denn hier Smalltalk (das im übrigen mit kleinem "t" geschrieben wird) durch das Raster? Smalltalk nutzt ein klassenbasiertes Objektmodell - wie eben auch Java, C++, C#, ...
    Bei Javascript sieht die Sache in der Tat etwas anders aus.

    [
    | Versenden | Drucken ]
    • 0
      Von Bolitho am Do, 12. April 2012 um 18:31 #

      Stimmt. Ich dachte daran, dass bei Smalltalk eine Klasse auch ein Objekt ist, aber das passt dann doch eher in die Python / Ruby Kategorie.

      [
      | Versenden | Drucken ]
      • 0
        Von t-bot am Do, 12. April 2012 um 22:14 #

        Um Dich vollkommen zu verwirren: Du hast recht! Klassen sind in Smalltalk Objekte. Das liegt aber an der (besonderen) internen Struktur von Smalltalk und dem Konzept "Alles ist ein Objekt".
        Allerdings ändert das wiederum nichts an der Tatsache, dass eine Klassenhierarchie existiert und über die Klassen Objekte instanziiert werden können.
        In prototypbasierten Sprachen wir Javascript werden die Objekte durch klonen erzeugt - dort gibt es keine Klassen und schon gar nicht Objekte, die Klassen sind.
        Python arbeitet bekanntlicherweise ebenfalls klassenbasiert, daher lässt sich das Modell des Artikel m.E. problemlos auch damit implementieren.

        [
        | Versenden | Drucken ]
        • 0
          Von Bolitho am Fr, 13. April 2012 um 13:37 #

          Du hast recht, man könnte den Vorschlag des Artikels z.B. in Python so umsetzen. Aber vieles davon würde ich anders gestalten; die ominöse Game-Klasse bräuchte man da z.B. nicht wirklich. Über Strategie-Pattern haben wir ja schon gesprochen ;-)

          [
          | Versenden | Drucken ]
    0
    Von js am Fr, 13. April 2012 um 01:03 #

    Da hat wohl jemand JavaScript nicht verstanden.

    JavaScript ist objektorientiert. Und zwar komplett. Allerdings wurden Keywords zur Definition von Klassen im aktuell verwendeten Standard noch nicht implementiert. Dennoch spricht man von einer Prototype-basierten Objektorientierung.

    // Das ist ein Konstruktor
    var MeineEigeneKlasse = function() {
    alert('Konstruktor');
    };


    MeineEigeneKlasse.prototype.hatEinAttribut = 33;
    MeineEigeneKlasse.prototype.hatEineMethode = function(inputV) {
    alert('eigeneMethode: ' + inputV);
    this.hatEinAttribut = inputV;
    };


    // Funktionaler/Prozeduraler Ansatz:
    MeineEigeneKlasse();

    // OOP-Ansatz
    var inst = new MeineEigeneKlasse();
    inst.hatEineMethode('neuerAttributWert');

    alert(inst.hatEinAttribut);

    Vererbung etc. pp. geht auch. Dadurch dass Du den Prototypen von Instanzen zur Laufzeit ändern kannst, ist es sogar extrem flexible OOP die in JS möglich ist. Das kann, wenn man es nicht vollständig verstanden hat, aber auch schlechte Folgen haben.

    Array.prototype.meinIndexOf = function() {
    return this.length;
    }

    var lala = ['abc', 123];

    alert(lala.meinIndexOf);

    Wie ihr seht: Man kann sogar die Prototypen bestehender Datentypen verändern. Zur Laufzeit. Die Instanzen ändern sich dabei auch...

    Und noch was: abkürzungen wie:

    var abc = "lala";

    kann man auch so schreiben: var abc = new String("lala");

    und

    var abc = ['lala'];

    auch als

    var abc = new Array();
    abc[0] = 'lala';

    etc. pp.

    [
    | Versenden | Drucken ]
    • 0
      Von t-bot am Fr, 13. April 2012 um 08:23 #

      Da hat wohl jemand OOP nicht verstanden - und gründlich gelesen hat er auch nicht.
      Niemand hat behauptet, dass JavaScript nicht objektorientiert wäre!
      Des Weiteren:
      JavaScript arbeitet prototypbasiert.
      JavaScript arbeitet NICHT klassenbasiert.
      So in der Art haben wir alle das gleiche gesagt - auch Du bevorzugt hast, es besonders verwirrend zu formulieren.

      Deine Beispiele sind leider Quatsch.
      "MeineEigeneKlasse" ist alles andere als eine Klasse, sondern ein Objekt. Und es wurde nicht über einen Konstruktor und eine Klasse erzeugt, sondern durch Klonen des Objects "function".

      Natürlich ist mit JS Objektorientierung möglich - logisch. Sogar sehr flexibel und dynamisch. Aber eben nicht klassenbasiert. Daher kann der Ansatz des Artikels auch nicht 1:1 übernommen werden, sondern die Lösung muss angepasst werden. Die Implementierung muss daher nicht einmal zwangsläufig schlechter sein, auch das hat niemand behauptet. Aber eben anders - prototypbasiert und dynamisch!

      [
      | Versenden | Drucken ]
      0
      Von experte32 am Fr, 13. April 2012 um 11:17 #

      >JavaScript ist objektorientiert. Und zwar komplett
      Falsch. Und zwar komplett.

      >Da hat wohl jemand JavaScript nicht verstanden.
      Wohl eher du.

      [
      | Versenden | Drucken ]
      • 0
        Von JavascriptExperte27 am Fr, 13. April 2012 um 20:08 #

        >>JavaScript ist objektorientiert. Und zwar komplett
        >Falsch. Und zwar komplett.
        Grob falsch. JavaScript *ist* objektorientiert. Ironischerweise sogar noch strenger als Java oder C++:
        - *alles* was du im Speicher hälst ist ein Objekt: von der Funktion über das Array bis hin zur schnöden Zahl (in Java ist nichts davon ein Objekt, in C++ strenggenommen ebenfalls nichts davon)
        - die Objektorientierung in Java und C++ ist eine Untermenge derer von JavaScript. prototypejs.org ist ein Beispiel eines bekannten JS-Frameworks, das die JS-Objektorientierung so aussehen lässt wie die von Java oder C++. (Versuch umgekehrt mal in Java oder C++ Prototypen-basierte OO zu machen.)

        >>Da hat wohl jemand JavaScript nicht verstanden.
        >Wohl eher du.
        Wer noch kein ernsthaftes Programm in JavaScript geschrieben hat, sollte lieber den Mund nicht so voll nehmen. Dein Vorposter hat sich offenbar schon sehr mit prototypenbasierter Objektorientierung in JavaScript auseinandergesetzt. Du hast dich anscheinend nicht einmal mit den Basics der Sprache auseinandergesetzt.

        [
        | Versenden | Drucken ]
        • 0
          Von LH_ am Sa, 14. April 2012 um 11:08 #

          "Grob falsch"

          Nein, er hat recht. JS ist Prototypen-basiert. Damit lässt sich klassische Objektorientierung umsetzen, was auch fast immer passiert, aber auch andere Muster lassen sich nachbilden.

          Auch ist das OOP in C++ und Java keine "untermenge" von dem was JS macht, es sind einfach unterschiedliche Ansätze. In C++ und Java ist vieles teil der Sprache, in JS werden viele OOP Elemente durch Frameworks umgesetzt. Sie könnten aber auch andere Ansätze damit umsetzen.

          JS Prototypen-basierter Ansatz erlaubt OOP, damit ist JS aber noch nicht selbst eine reine OOP Sprache.

          Es ist ein wenig wie bei Lego: Du kannst damit fast alles machen, aber am Anfang sind es eben nur Bauklötze.
          Kurzum: Ja, JS lässt sich gut für OOP nutzen, es ist jedoch weder zwingend, noch der einzige Weg. Es ist ein möglicher Pfad, den man beschreiten kann.

          [
          | Versenden | Drucken ]
    0
    Von hans wurst am Fr, 13. April 2012 um 19:44 #

    Du kannst jedes UML-Diagramm auch in C oder Basic implementieren.

    Habe den Artikel zwar nur überflogen, aber so wie ich es verstehe, liegt die Betonung hier auf OOA/OOD (Objektorientierte Analyse/Objektorientiertes Design). Diese Disziplin wird in manchen Fällen nicht einmal von Programmierern durchgeführt.

    Es ist ja auch so, wenn du dich etwa in Java spezialisieren willst, dann schadet es trotzdem nicht C# zu lernen. Eventuell gibt es dort Denkweisen, die du in Java bisher nie gedacht hattest.

    [
    | Versenden | Drucken ]
    • 0
      Von Bolitho am Fr, 13. April 2012 um 20:07 #

      Du kannst jedes UML-Diagramm auch in C oder Basic implementieren.
      Ahja... und wie soll das gehen? Wie ist denn das Mapping von einem Klassendiagramm auf eine Klassen lose Sprache definiert? Wäre mir neu, wenn es da eine standardisierte Vorgehensweise gäbe...

      Ich habe ja explizit auf "Klassen" zentrierte OOP in meinem Beitrag hingewiesen. Beiträge wie Deiner zeigen mir eher, dass es da draußen bei vielen nur ein oberflächliches und vor allem beschränktes Wissen über solche Sachen gibt. Daran sind natürlich viele Quellen schuld, die Java als *die* OOP Sprache anpreisen... :evil:

      [
      | Versenden | Drucken ]
      • 0
        Von hans wurst am Fr, 13. April 2012 um 20:18 #

        >Ahja... und wie soll das gehen? Wie ist denn das Mapping von einem Klassendiagramm auf eine
        >Klassen lose Sprache definiert? Wäre mir neu, wenn es da eine standardisierte Vorgehensweise
        >gäbe...

        Kommt ganz auf die Sprache an. Übrigens gibt es selbst in Java/C++ kein "standartisiertes Vorgehen". Niemand hindert dich daran ein Diagramm rein funktional zu implementieren, so lange der Code strukturgleich ist.

        Aber naja, in C gibt es ein mehr oder weniger standartisiertes Vorgehen, wenn man explizit von OO in C spricht: structs und Funktionenpointer. Alternativ: structs und dann für die Instanzmethoden immer als ersten Parameter den struct übergeben.

        >Ich habe ja explizit auf "Klassen" zentrierte OOP in meinem Beitrag hingewiesen. Beiträge
        >wie Deiner zeigen mir eher, dass es da draußen bei vielen nur ein oberflächliches und vor
        >allem beschränktes Wissen über solche Sachen gibt. Daran sind natürlich viele Quellen
        >schuld, die Java als *die* OOP Sprache anpreisen... :evil:
        Ohne darauf näher einzugehen, dein Kommentar zu Smalltalk beweist, dass du ziemlich oberflächlich vorgehst: Smalltalk wird, von Leuten die die Sprache kennen, als *die* OOP-Sprache gerühmt. Die Sprache ist übrigens sehr einflussreich gewesen in der Evolution vieler heutiger dynamischer Sprache.

        [
        | Versenden | Drucken ]
        • 0
          Von Bolitho am Sa, 14. April 2012 um 09:12 #

          Die Argumentation mit der Umsetzung ist doch krude! Was nützt es einem Konzepte zu modellieren, die es in der Zielsprache schlicht nicht gibt? Ein Klassendiagramm enthält nebenbei gesagt kaum Funktionalität; da geht es primär um die Strukturierung. Natürlich kann ich (mit zusätzlichen Angaben) ein Programm in einer beliebigen Sprache schreiben, die die Intention des UML-Diagramms umsetzt - aber wo ist da noch die "Hilfe" von UML? Wo sehe ich den Einfluss / die Verbindung zwischen Modell und Code?

          Du kannst das drehen wie Du willst: Klassendiagramme (und darauf basierende) machen für Sprachen ohne Klassen einfach keinen Sinn! Da die Modellkonzepte nur über Umwege im Code erkennbar sind, kann ich mir so ein Modell gleich sparen und lieber mit Modellen arbeiten, die eine leicht nachvollziehbare Abbildung in Code erlauben.

          Und ich habe Smalltalk niemals seine OOP- Qualitäten abgesprochen! Verfälsche die Tatsachen nicht.

          [
          | Versenden | Drucken ]
          • 0
            Von hans wurst am So, 15. April 2012 um 15:16 #

            >Du kannst das drehen wie Du willst: Klassendiagramme (und darauf basierende) machen für
            >Sprachen ohne Klassen einfach keinen Sinn!

            Für Javascript sehe ich keine Hindernisse, aber da brauchen wir glaub ich nicht drüber zu diskutieren.

            Aber sagen wir, wir reden von C: darin soll eine Software implementiert werden, an der 5 Leute arbeiten. Die Software ist außerdem so groß, dass es keinen Sinn macht, dass sich jeder in allen Code-Teilen perfekt auskennen. Besser ist, wenn jeder sich auf bestimmte Funktionalitäten spezialisiert. Außerdem ist die Software multithreaded.

            Da sagt der Verantwortliche natürlich: die Software muss irgendeine Modularität aufweisen. Diese Modularität muss gut isolieren. Also etwa verhindern, dass in Modul A Variablen von Modul B geändert werden, die überhaupt nicht in den Zuständigkeitsbereich von A fallen.

            Da die Software Multithreaded ist, soll ohnehin verhindert werden, dass Funktionen in Modul A Variablen von B ändern können. Und sei es ganz über Umwege durch interne Hilfsfunktionen, die für sich genommen der geringeren Komplexität wegen nicht thread-safe sind, etwa:

            /* modul_b.c */
            /* ... */
            void increment() {
            foo++;
            }
            /* ... */

            Da kannst du es drehen wie du willst, aber letztendlich brauchst du dafür ein zu Klassen isomorphes Konzept. C kennt weder Namespaces, Module oder Klassen. Funktionen sind immer global und öffentliche Variablen im Prinzip auch. (Außer man benutzt Funktionenzeiger.)

            Im Linux-Kernel wird das zB dadurch simuliert, dass alle Funktionen immer ein Prefix haben. Z.B. in kernel/audit.c fangen alle Funktionen und öffentliche Variablen mit audit_ an.

            Oder schau dir den struct audit_buffer an:
            - es gibt die Funktionen audit_buffer_free (Destruktor) und audit_buffer_alloc (Konstruktor)
            - die meistens Funktionen (mit nicht-trivialer Funktionalität) haben audit_buffer als erstes Argument

            Natürlich kannst du jetzt kommen und sagen: aha, was was ist dann mit Polymorphie und Vererbung? Öffentliche Vererbung und Polymorphie kann man durchaus als Bad-Practise ansehen. Siehe zB hier. Manche C++-Experten raten sogar komplett auf öffentliche Vererbung zu Verzichten und stattdessen die zu erbenden Klassen in Instanzvariablen zu stecken. Die Kapselung ist so viel überschaubarer. Stattdessen soll man auf Interfaces bzw. abstrakte Klassen setzen (Google Go etwa verfolgt genua dieses Konzept, es hat keine Vererbung wie man sie von Java oder C++ kennt.)

            [
            | Versenden | Drucken ]
0
Von experte32 am Fr, 13. April 2012 um 11:15 #

Das Buch ist auf dem Niveau von xy in 21 Tagen oder der Dummiesreihe und ähnlichem Schund.

Der Artikel liest sich wie wenn ein Erstsemester seinen Vorlesungserlebniss zum thema OOA/D in einem "Artikel" gesammelt hätte.

Bitte einstellen, das wird sonst noch peinlicher.

[
| Versenden | Drucken ]
Pro-Linux
Pro-Linux @Facebook
Neue Nachrichten
Werbung