Thomas: OOP-Anfängerfrage... Klassenstruktur

Moin,

lese mich gerade in OOP in PHP ein. Hab IMHO das Prinzip auch halbwegs verstanden. Jetzt spiele ich gerade etwas rum. Das klappt auch ganz gut, aber ich wundere mich etwas, über die Strultur der Klassen, die dabei enstehen. Ich habe immer riesige Konstruktoren, in denen sich alles abspielt, gefolgt von winzigen Funktionen, die nichts anderes machen, als die gesetzten Variablen zurückzugeben. Da habe ich wohl noch irgendeine OOP-Denkblockade, oder?

So sehen meine Klassen im Prinzip aus:

class name_der_klasse
{
 var $a;
 var $b;
 var $c;

name_der_klasse($x, $y, $z)
  {
   /*
   hier steht jede Menge Code
   und zwischendrin werden die
   Variablen $a, $b und $c gesetzt...
   */
   $this -> a = 'irgend was';
   $this -> b = 'noch was';
   $this -> c = 'sonst was';
  }

function return_a()
  {
   return $this->a;
  }

function return_b()
  {
   return $this->b;
  }

function return_c()
  {
   return $this->c;
  }
}

Schon mal Danke für Hilfe!
Thomas

  1. Hej,

    also ich bin nur mit der OOP in Java vertraut und kenne Deine Sorge nur zu gut. Überlege Dir bitte nochmal was der Konstruktor macht: Er dient nur dazu das Objekt mit seinen Eigenschaften anzulegen.

    Demzufolge hätte das Objekt das Du anlegst folgende Merkmale:
    * Ist es einmal angelegt, kann es nicht verändert werden.
    * Es kann nur Auskunft über seine Attribute geben.
    * Die Eigenschaften die es hat sind so einfach anzulegen, dass es sich nicht lohnt private Methoden zu schreiben, auf die vom Konstruktor aus zugegriffen wird.

    In dem Moment wo Du aber für eine Klasse mehrere überladene Konstruktoren verwendest, oder die Eigenschaften eines Objektes nach dem Anlegen veränderlich halten möchtest, oder welche hinzufügen möchtest, wird Deine Klasse schnell um entsprechende Methoden wachsen.

    Viele Grüße

    Biesterfeld

    1. Hallo Biesterfeld,

      das hat mir schon mal ein Stück weitergeholfen, Danke!

      Viele Grüße
      Thomas

    2. Hallo,

      Demzufolge hätte das Objekt das Du anlegst folgende Merkmale:
      * Ist es einmal angelegt, kann es nicht verändert werden.
      * Es kann nur Auskunft über seine Attribute geben.

      In diesem Fall, sollte man sich überlegen, ob man wirklich eine Klasse braucht. Möglicherweise reicht ja auch ein einfaches assoziatives Array.

      * Die Eigenschaften die es hat sind so einfach anzulegen, dass es sich nicht lohnt private Methoden zu schreiben, auf die vom Konstruktor aus zugegriffen wird.

      Doch, das lohnt sich immer. Wenn jemand die Klasse benutzen will, brauch er nicht zu wissen, wie die Daten intern gespeichert sind (Stichwort »Information-Hiding«). Und sollte es mal der Fall sein, dass man die Datenspeicherung intern aus irgendwelchen Gründen anders lösen möchte, sind entsprechende Methoden von Vorteil, da sich die Schnittstelle nicht zu ändern braucht.

      Zwar mögen diese Gründe, bei sehr kleinen und einfachen Klassen unwichtig sein, aber da sollte man sie allein schon deshalb hinzufügen, damit die Schnittstellen einheitlich sind und der Anwender der Klassen nicht jedesmal überlegen muss, ob es eine entsprechende Methode gibt oder er auf das Feld direkt zugreifen muss.

      In dem Moment wo Du aber für eine Klasse mehrere überladene Konstruktoren verwendest, oder die Eigenschaften eines Objektes nach dem Anlegen veränderlich halten möchtest, oder welche hinzufügen möchtest, wird Deine Klasse schnell um entsprechende Methoden wachsen.

      Genau, deine Klasse, Thomas, besteht gerade nur aus ein paar Feldern mit vordefinierten Werten und den entsprechenden Get-Methoden. Du hast noch nicht einmal Set-Methoden um den Wert der Felder zu ändern. In der Regel bestehen Klassen jedoch auch noch aus anderen Methoden, die mehr können. Das ist auch ihr Vorteil gegenüber simplen Strukturen, wie man sie z.B. von C kennt.

      Schöne Grüße,

      Johannes

      --
      Das sage ich deshalb, weil ich Hompagebauer bin und Ahnung davon .
      ss:| zu:) ls:[ fo:) de:] va:) ch:) n4:| rl:) br:< js:| ie:{ fl:( mo:}
  2. ich hatte das gleiche problem mit einer mitarbeiterin. diese hat einfach den prozeduralen teil in eine klasse gepackt und den konstruktor aufgerufen. in diesem fall kann man den konstruktor auch statisch aufrufen, ohne eine instanz der klasse zu erzeugen.

    So sehen meine Klassen im Prinzip aus:

    class name_der_klasse
    {
    var $a;
    var $b;
    var $c;

    name_der_klasse($x, $y, $z)
      {

    hier steht dein prozedurales programm

    /*
       hier steht jede Menge Code
       und zwischendrin werden die
       Variablen $a, $b und $c gesetzt...
       */
       $this -> a = 'irgend was';
       $this -> b = 'noch was';
       $this -> c = 'sonst was';

    hier endet dein prozedurales programm

    }

    function return_a()
      {
       return $this->a;
      }

    function return_b()
      {
       return $this->b;
      }

    function return_c()
      {
       return $this->c;
      }
    }

    die idee der objektorientierung ist ua. die sammlung von progrämmchen mit gemeinsamen daten in einer klasse.
    ein beispiel mag die MATH klasse sein. diese progrämmchen werden zwar nur statisch aufgerufen. aber du hast zb. MATH.sin, MATH.cos usw., also eine sammlung von progrämmchen schön nach zusammenhang geordnet.
    mit diesem gedankenansatz fällt dir die umsetzung hoffentlich etwas leichter.

    du solltest in deinem konstruktor nur die anfangswerte setzen. wenn du dann eine instanz der klasse erzeugst, hat das objekt definierte ausgangswerte.

    dann könnte es eine methode 'arbeit' geben, welche im ersten ansatz einfach dein bisheriges prozedurales programm ist.
    dieses könnstest du dann in kleinere einzelteile zerlegen, und durch methodenaufrufe ersetzen.

    hast du genügend kleine methoden erstellt, kannst du dich wieder dem konstruktor zuwenden, und die übergebenen parameter auswerten und in deren abhängigkeit die kleinen methoden aufrufen.

    willst du später mal mehr funktionalität in die klasse einbauen, machst du einfach eine neue methode.

  3. Hallo Thomas,

    Da habe ich wohl noch irgendeine OOP-Denkblockade, oder?

    Wenn alle Deine Klassen so aussehen, programmierst Du vermutlich nach wie vor prozedural.

    Beim prozeduralen Programmieren hat man normalerweise einige Datenstrukturen und wendet darauf irgend welche Algorithmen an. Die Gliederung der Algorithmen hat mit der Struktur der Daten eher wenig zu tun.

    Beim objektorientierten Programmieren strukturiert man die Algorithmen anhand der Daten. Man ordnet eher kleine Teilalgorithmen einzelnen Objekten zu.
    Du kannst ja mal Dein konkretes Beispiel beschreiben, daran kann man vielleicht besser veranschaulichen.

    An Klassen, wie der genannte Math-Klasse mit statischen Methoden ist übrigens rein gar nichts objektorientiert. Da kann man dieses Konzept auch nicht sinnvoll anwenden.

    Grüße

    Daniel

    1. es handelt sich um eine anfängerfrage.
      man sollte anfänger nicht gleich mit den erfahrungen der jahrzehntelangen programmierprobleme, welche zur objektorientierung geführt haben, überfallen.
      es reicht im ersten ansatz aus, nur auf die kapselung zu achten.
      nach einiger übung entwickelt auch ein anfänger höhere ansprüche und entdeckt die vollen vorteile der oop.
      dann kann auch sinnvoll mit objektbäumen gearbeitet werden.

      ps:
      das prozedurale vorgehen entspricht eher dem menschlichen 'workflow' denken: 1. dies, 2. das usw...

      das objektorientierte vorgehen basiert auf der kommunikation der objekte miteinander.
      jede kommunikation wird aber durch ein ereignis ausgelöst (anders als bei menschen, diese unterhalten sich auch gern ohne besonderen grund).
      daher muß bei vollständiger betrachtung auch die ereignisauslösung berücksichtigt werden.
      hier wird dann besonders deutlich, was für eine kausale kette ein ereignis auslösen kann.

      von daher ist objektorientierung nur eine kommunikation zwischen objekten, welche nur ihre eigenen daten kennen.

      die aussage, oop sei, aus daten auf algorythmen abzuleiten, ist daher nur in der kleinen sicht eines objektes gültig.

      1. Hallo fk,

        Naja man kann diesen Perspektivenwechsel machen oder nicht. Wenn man ihn nicht macht, macht der Einsatz von OO-Sprachfeatures die Programme höchstens schlechter.
        Von daher ist es schon wichtig, die Idee zu verstehen. An der Uni Stuttgart wird z.B. OO-Entwurf mit UML gelehrt bevor überhaupt begonnen wird, objektorientierte Programmiersprachen zu verwenden, was ich für eine sehr gute Idee halte.

        die aussage, oop sei, aus daten auf algorythmen abzuleiten, ist daher nur in der kleinen sicht eines objektes gültig.

        Ich habe nicht gesagt, dass man die von den Daten ableitet, sondern sie Anhand der Struktur der Daten (Zerlegung der Daten in Objekte) strukturiert.

        Grüße

        Daniel

        1. Naja man kann diesen Perspektivenwechsel machen oder nicht. Wenn man ihn nicht macht, macht der Einsatz von OO-Sprachfeatures die Programme höchstens schlechter.

          die perspektive wird bei dem oop diskussionen oft nicht beachtet. wenn man diese auf die klasse beschränkt liegst du völlig richtig.

          Von daher ist es schon wichtig, die Idee zu verstehen. An der Uni Stuttgart wird z.B. OO-Entwurf mit UML gelehrt bevor überhaupt begonnen wird, objektorientierte Programmiersprachen zu verwenden, was ich für eine sehr gute Idee halte.

          uml ist ja nicht auf die konkrete entwicklung der klasse bezogen, sondern zur erkennung der objekte. dies hat im grunde ja nicht einmal etwas mit programmieren zu tun.

          die aussage, oop sei, aus daten auf algorythmen abzuleiten, ist daher nur in der kleinen sicht eines objektes gültig.
          Ich habe nicht gesagt, dass man die von den Daten ableitet, sondern sie Anhand der Struktur der Daten (Zerlegung der Daten in Objekte) strukturiert.

          ich will hier auch keine wortklauberei betreiben. diese gedankenansätze gelten ja auch bei der prozeduralen vorgehensweise. eine methode einer klasse ist ja auchn nichts weiter, als ein prozeduraler ablauf.

          dies ganze gedöns der zusammenhänge von daten und algorythmen lenkt auch die konzentration auf das wesentliche ab. ich habe seinerzeit mal die anfänge von entity-modell und funktions-modell mitgemacht, und sollte damit ein projekt erstellen. ich konnte es den experten nicht recht machen, da wir immer wieder auf die ursache-wirkung problematik stießen. so muß man dann einen operativen prozeß in einem unternehmen soweit zurückverfolgen, daß die frage entsteht: 'warum das ganze'. die einzige antwort: profit ! damit wären wir auch bei dem ur-ereignis der objektkommunikation.

          1. Hallo fk,

            uml ist ja nicht auf die konkrete entwicklung der klasse bezogen, sondern zur erkennung der objekte. dies hat im grunde ja nicht einmal etwas mit programmieren zu tun.

            Naja Klassendiagramme sind eigentlich sehr konkret auf die Entwicklung von Klassen bezogen.

            Ich habe nicht gesagt, dass man die von den Daten ableitet, sondern sie Anhand der Struktur der Daten (Zerlegung der Daten in Objekte) strukturiert.

            Ok, das ist hier nicht ganz korrekt formuliert. Sie sind dann entsprechend den Daten strukturiert, man geht natürlich nicht so vor, dass man die Algorithmen schon hat und die dann auf Klassen verteilt, sondern man hat eben eine gewisse Struktur praktisch gegeben (auch wenn es natürlich nicht ganz einfach ist, diese zu erkennen und Klassen daraus abzuleiten) und baut seine Algorithmen da dann ein. Was ich verdeutlichen wollte, ist, dass OOP diese typische Trennung von Daten und Algorithmen aufhebt.

            Grüße

            Daniel

            1. Ok, das ist hier nicht ganz korrekt formuliert. Sie sind dann entsprechend den Daten strukturiert, man geht natürlich nicht so vor, dass man die Algorithmen schon hat und die dann auf Klassen verteilt, sondern man hat eben eine gewisse Struktur praktisch gegeben (auch wenn es natürlich nicht ganz einfach ist, diese zu erkennen und Klassen daraus abzuleiten) und baut seine Algorithmen da dann ein. Was ich verdeutlichen wollte, ist, dass OOP diese typische Trennung von Daten und Algorithmen aufhebt.

              das ist völlig richtig. deshalb habe ich betont, daß die kommunikation der objekte im vordergrund steht. welche daten das objekt 'intern' hat, ist der kommunikation völlig egal.

              dem fragesteller ist wohl mehr an der konkreten klasse gelegen. diese ohne kenntnis des zusammenhangs zu erstellen wirft dann natürlich probleme auf. daher sollte man auf 'klassensicht' erst mal ein prozedurales programm in teilaufgaben zerlegen, und vom konstruktor aus eine art 'verteiler' basteln, welche die methoden aufrufen.
              der rest kommt dann später sowieso.

              wo ist der 'geborene meister', welcher das komplette konzept von objekten mit der muttermilch eingesogen hat?

  4. Hallo,

    habe gerade erst bemerkt, dass da noch Antworten hinzugekommen sind:
    Danke an Euch alle! Ich werde mir das jetzt mal zu Gemüte führen!

    Thomas