generelle Datenkapselung sinnvoll?

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • generelle Datenkapselung sinnvoll?

    Gibt es praktische Gründe, die für eine generelle Datenkapselung sprechen (keine public Attribute, immer setter und getter)?
    Wenn beim Setzen des Attributes weitere Aktionen ausgeführt werden sollen oder beim Lesen bspw. dynamisch etwas zurückgegeben werden soll, dann macht Datenkapselung natürlich Sinn.
    Aber warum auch andere Variablen, deren getter / setter wie im folgenden aufgebaut sind, kapseln?
    PHP-Code:
    class c
    {
    private 
    $a;
    public function 
    getA()
    {
    return 
    $this->a;
    }
    public function 
    setA($value)
    {
    $this->a=$value;
    }

    Auch das Argument, dass bei anfänglicher Planung keine weiteren Aktionen beim Setzen / Lesen ausgeführt werden sollen und dann nachträglich doch noch eine setter Methode benötigt wird, lässt sich dadurch entkräften, dass man über __get() und __set() diese auch noch nachträglich hinzufügen kann in einer abgeleiteten Klasse z.B.
    Der durch die magischen Methoden entstehende Performance-Verlust lässt sich vermutlich durch das Einsparen der vielen get / set Methoden kompensieren.

    Sind da Gründe für eine generelle Datenkapselung, die ich nicht kenne?

  • #2
    Manche Sprachen unterstützen sachen wie "readonly" Felder nicht. Einzige Möglichkeit: nur einen getter definieren und das tatsächliche Attribut verstecken.

    Ansonsten hat man in PHP mit den von dir erwähnten Konstrukten schon sehr gutes Werkzeug an der Hand.

    Hat man aber eben nicht überall, und das muss man bedenken.
    This is what happens when an unstoppable force meets an immovable object.

    Kommentar


    • #3
      Der Hauptgrund für Datenkapselung ist sicherlich die Kontrolle von Eingabewerten. Eine Instanz einer Klasse – ein Objekt – sollte in der Regel dafür sorgen, dass es sich immer in einem gültigen Zustand befindet. Das ist sicherlich einer der Hauptzwecke von OOP.

      PHP-Code:
      class Person
      {
          public 
      $name 'Dummy';
      }

      $p = new Person();
      $p->name = -12.7
      Hier ist es möglich, $p sinnlose Werte zu setzen und das Objekt in einen ungültigen Zustand zu bringen.

      Zitat von einermeiner
      Auch das Argument, dass bei anfänglicher Planung keine weiteren Aktionen beim Setzen / Lesen ausgeführt werden sollen und dann nachträglich doch noch eine setter Methode benötigt wird, lässt sich dadurch entkräften, dass man über __get() und __set() diese auch noch nachträglich hinzufügen kann in einer abgeleiteten Klasse z.B.
      Das geht meines Wissens nicht.

      PHP-Code:
      class Foo
      {
          public 
      $bar;
      }

      class 
      Baz extends Foo
      {
          protected 
      $boz;

          public function 
      __get($name)
          {
              
      printf(
                  
      "%s::%s called for %s\n",
                  
      __CLASS____FUNCTION__$name
              
      );
          }

          public function 
      __set($name$value)
          {
              
      printf(
                  
      "%s::%s called for %s\n",
                  
      __CLASS____FUNCTION__$name
              
      );
          }
      }

      $b = new Baz();

      // No output
      $b->bar;
      $b->bar '';

      // Output
      $b->boz;
      $b->boz ''
      Beim Einsatz von magischen Methoden besteht zudem immer das Problem, dass Teile des API einer Klasse verdeckt werden. Es wird sehr schwierig oder sogar unmöglich, festzustellen, welche öffentlichen Instanzvariablen eine Klasse denn nun hat.

      Kommentar


      • #4
        Das geht meines Wissens nicht.
        Stimmt, ich hatte nicht daran gedacht, dass die abgeleitete Klasse mindestens die gleiche Sichtbarkeit wie die Elternklasse haben muss.

        Das von mir verwendete Framework arbeitet allerdings häufig mit den magischen Methoden...

        Kommentar


        • #5
          Ich glaube, der Aspekt ist hier eher Willkür aka Designentscheidung.

          - PHP: Overloading - Manual

          __set() is run when writing data to inaccessible properties.

          __get() is utilized for reading data from inaccessible properties.
          Öffentliche Instanzvariablen sind nicht inaccessible genug.


          Ich denke, __get und __set sind möglicherweise akzeptabel, wenn die Klasse ein generischer Container ist, der sonst so funktionieren würde:

          PHP-Code:
          $c->set('key'$value);
          $c->get('key'); 
          Hier wird eine beliebige Anzahl von „Instanzvariablen“ verwaltet.

          Vier Unterstriche mehr im Klassencode und es wird zu:

          PHP-Code:
          $c->key $value;
          $c->key
          Weiß nicht, über solche Fragen habe ich bisher noch nie besonders intensiv nachgedacht. Es spart schon Tipparbeit, nicht immer get('') hinzufügen zu müssen. Convenience shortcuts sind wichtig. Das klassische Beispiel für magische Getter sind sicherlich View-Klassen mit Template-Scripts im Stile von Zend_View.

          PHP-Code:
          $view->foo 'Hello World'
          PHP-Code:
          <p><?=$this->foo?></p>

          Kommentar


          • #6
            Im Yii-Framework ist dies auch die Vorgehensweise beim Eintragen von Daten in das Model, die Validierung findet über eine Methode validate(), die aber separat aufgerufen werden muss.

            Kommentar

            Lädt...
            X