2012-06-23 10 views
12

Ich brauche ca. erstellen. 5-7 Klassen, jede Klasse enthält viele Mitglieder (sagen wir mal, jede Klasse wird 20 Mitglieder enthalten). Ich konnte sie mit dem öffentlichen Zugang erstellen, wie:PHP OOP eine Menge Setter, Getter

class A { 
    public $myPropertyOne = ''; 
    public $myPropertyTwo = ''; 
    ... 
} 

Meine bevorzugte Art und Weise natürlich diese Elemente privat zu machen und für jede Eigenschaft get/set-Methoden erstellen. I.e.

class A { 
    private $myPropertyOne = ''; 
    private $myPropertyTwo = ''; 

    public function getMyPropertyOne() { 
      return $this->myPropertyOne; 
    } 

    public function setMyPropertyOne($myPropertyOne) { 
      $this->myPropertyOne = $myPropertyOne; 
    } 

    public function getMyPropertyTwo() { 
      return $this->myPropertyTwo; 
    } 

    public function setMyPropertyTwo($myPropertyTwo) { 
      $this->myPropertyTwo = $myPropertyTwo; 
    } 
} 

Aber wenn man bedenkt, dass eine Klasse 20 Eigenschaften haben wird, werde ich zusätzlich 40 Methoden hinzufügen. Und meine Sorge hier ist, wie wird dies verlangsamen das Skript und viel mehr Speicher das wird erfordern (erinnere mich, ich werde mehrere Klassen wie folgt haben).

Eine andere Lösung könnte sein, die magischen Funktionen __set, __get zu verwenden, aber das möchte ich nicht, weil die Codevervollständigung in der Entwicklungs-IDE keine Eigenschaften vorschlägt, die für mich entscheidend sind.

Wenn dies eine kompilierte Sprache wäre (wie C++) hätte ich keine Frage und würde die Lösung mit Gettern, Setter verwenden, aber da die Sprache PHP interpretiert ist, interessieren mich meine Skripts, weniger RAM zu verwenden und so zu sein so schnell wie möglich.

Vielen Dank im Voraus, alle Gedanken zu dieser Frage würden sehr geschätzt werden!


Meine Meinung

Vielen Dank für Ihre Antworten, ich wollte nur auf diese Frage eine Antwort aussehen wird meiner Meinung nach, falls jemand teilen.

Ich kann nicht voll und ganz mit denen einverstanden sein, die sagen, dass Sie sich nicht um Leistung kümmern sollten, da dies die Aufgabe von Optimierern ist, ich denke, dass dies ein wichtiger Faktor ist (gut zumindest für mich), wenn wir mit interpretierter Sprache wie PHP müssen wir immer über Speicher und Geschwindigkeit nachdenken (das erinnert mich an die Zeit, als ich System-Apps für DOS entwickelte, heh :) und Sie waren immer mit schlechter CPU und Kilobyte Gesamt-RAM begrenzt, so dass Sie glücklich wurden, wenn Sie könnte ein zusätzliches Byte speichern), in PHP Entwicklung haben Sie das gleiche Bild als unabhängig davon, wie viele Server Sie hinzufügen, die Anzahl der Benutzer wird immer höher sein, so dass Sie immer entscheiden müssen, ob Sie klassische/sichere/richtige Methode folgen oder um dies zu vermeiden und etwas an Geschwindigkeit oder Speicher zu gewinnen.

Also meine Meinung ist, dass der beste Weg hier ist, öffentlichen Zugriff für alle Mitglieder zu verwenden und Getter/Setter für alle Eigenschaften zu vermeiden und privaten Zugriff mit get/set-Methoden für Eigenschaften zu verwenden, die Datenvalidierung oder Initialisierung erfordern bevor ein Wert gesetzt wird.

Zum Beispiel:

class B { 
    public $myPropertyOne = ''; 
    public $myPropertyTwo = ''; 
    private $myPropertyThree = array(); 


    public function getMyPropertyThree() { 
     return $this->myPropertyThree; 
    } 

    public function setMyPropertyThree($val) { 
     if(!is_array($val)) { 
      return; 
     } 

     $this->myPropertyThree = $val; 
    } 
} 

Danke Zeit auf meine Frage zu verbringen!

+14

dies ist eine Mikro-Optimierung, und Sie sollten * nie * sich darüber sorgen. –

+0

Nun ja, aber eine Perspektive 280 hinzuzufügen Methoden (für 7 Klassen, 20 private Mitglieder) nur für diese ein wenig Angst vor Speicher/Geschwindigkeit Standpunkt. Und lassen Sie uns sagen System wächst und ich werde diese Klassen auf die Anzahl von 15 erweitern .. dann werde ich 600 Methoden bekommen Auf der anderen Seite stelle ich fest, dass diese Get/Set-Methoden nur bei Bedarf ausgeführt werden, aber gleichzeitig nehme ich an, dass wenn PHP Quellcode analysiert, es eine Tabelle von Methoden im Speicher erstellt, Syntaxanalyse durchführt und dies alles kann verlangsamen die Arbeit des Skripts viel, ist meine Annahme richtig? – user1476490

+1

Speicher ist relativ billig und Methode Overhead ist nur per-Klasse (nicht pro Instanz). PHP macht auch Tricks wie die Behandlung mehrerer Anfragen im selben Prozess (über mod_php, usw.) so kann die anfängliche Ladezeit (so trivial sie auch sein mag) völlig ignoriert werden ... in jedem Fall * Benchmark zuerst * (unter tatsächlichen Bedingungen) um zu sehen, was die "langsamen" Teile eines Systems sind. (FWIW, nehme an, dass es 600 Methoden gibt, und jede Methode "verschwendet" 1kb. Ein satte 600kb wird "verschwendet". Nicht wirklich so viel im Schema der Dinge ... besonders in Anbetracht wie viel * jede Variable * in PHP bereits " Verschwendung ";-) –

Antwort

5

Einfacher Test zeigt Fällen die gleiche Menge an Speicher nehmen, unabhängig von der Anzahl der Methoden in einer Klasse:

Klasse ohne Methoden:

class Test1 { } 

Klasse mit 20 Methoden:

class Test2 { 

    function test1() { return true; } 
    function test2() { return true; } 
    function test3() { return true; } 
    function test4() { return true; } 
    function test5() { return true; } 
    function test6() { return true; } 
    function test7() { return true; } 
    function test8() { return true; } 
    function test9() { return true; } 
    function test10() { return true; } 
    function test11() { return true; } 
    function test12() { return true; } 
    function test13() { return true; } 
    function test14() { return true; } 
    function test15() { return true; } 
    function test16() { return true; } 
    function test17() { return true; } 
    function test18() { return true; } 
    function test19() { return true; } 
    function test20() { return true; } 

} 

Testschleife, für beide Tests gleich:

$test = array(); 
$base = memory_get_usage(); 
for ($i = 0; $i < 10000; $i++) { 
    $test[] = new ClassToBeTested(); 
} 
$used = memory_get_usage() - $base; 
print("used: $used\n"); 

Ergebnis für Klasse Test1 (keine Methoden):

used: 3157408 

Ergebnis für Klasse Test2 (20 Methoden):

used: 3157408 

Ich habe es in zwei separate Skripte ausgeführt, da die beiden Tests laufen In einem einzigen Skript offenbar offenbar einige interne PHP-Zuweisung, und der zweite Test verbraucht weniger Speicher als der erste, egal welche erste oder zweite ist.

Während Sie sicher mehr Speicher für die eigentliche Klassendefinition nehmen, werden diese Kosten anscheinend nur einmal pro Klasse und nicht pro Instanz verursacht. Sie müssen sich keine Gedanken über die Speichernutzung machen.

+0

Ich kann hier leider nicht viel Code einfügen, aber hier ist was ich gemacht habe. Ich habe test1.php mit einer einzelnen Klasse darin erstellt, dann test2.php mit einer Klasse und einer einzigen Methode und dann test3.php mit der Klasse, 20 privaten Eigenschaften und dann 40 öffentlichen Get/Set-Methoden (mit allen Returns, etc). Und Ausgang Gesamt RAM am Ende verwendet wird, so ist hier, was ich habe: 'test1.php - 653,97 Kbytes' ' test2.php - 654,73 Kbytes' 'test3.php - 718,16 Kbytes' Dies ist rau, aber Grundsätzlich nehme ich an, dass jede Methode/Variable die Daten, die sie enthält, nicht zählt, isst ~ 1kb. – user1476490

5

Aber eine Klasse unter Berücksichtigung 20 Objekte

Mit so vielen Eigenschaften ein Indikator für fehl am Platze Informationen ist in der Regel hat. Überprüfen Sie, ob Sie einige dieser Klassen in eigene Klassen gruppieren können.

ich zusätzlich dazu werden 40 Methoden haben wird.

Überhaupt nicht. Wenn diese Klassen keine dummen Datenstrukturen sind, möchten Sie keine Getters und Setter für sie, da sie die Einkapselung unterbrechen. Setzen Sie Methoden in die öffentliche API, mit der Sie den Objekten sagen, dass sie Dinge tun sollen.

Und hier meine Sorge ist, wie wird diese verlangsamen das Skript und vieles mehr Speicher erfordert dies (ich erinnere mich einige haben werde Klassen wie diese).

Dies ist kein Problem.

könnte eine andere Lösung sein magische Funktionen nutzen __set, __get aber ich will nicht, weil der Code-Vervollständigung in Entwicklung IDE nicht Eigenschaften deuten darauf hin, was für mich ist entscheidend .

Moderne IDEs können auf magische Methoden automatisch vervollständigen.

Wenn Sie jedoch bereits besorgt über die Leistung an der Mikroebene sind, dann müssen Sie nicht magische Methoden wollen, weil diese auf jeden Fall langsamer sind.

Abgesehen davon sind Magische Methoden nicht als Ersatz für die Getter und Setter aber Fehlerbehandlungsroutinen, die ausgelöst werden, wenn eine unzugängliche Eigenschaft oder Methode aufgerufen wurde.

Auch sind magische Methoden nicht offensichtlich und machen für harte APIs zu lesen.

+0

Vielen Dank für Ihre ausführliche Antwort. – user1476490

0

Nehmen Sie daran, dass mein Code berücksichtigt, dass die Eigenschaften Name in Klein erklärt wurden ...

<?php 

    class Modelo { 
     var $attr1 = "default"; 
     var $attr2 = 0; 


     public function __call($name, $arguments) 
     { 
      if (method_exists($this, ($method = $name))){ 
       return $this->$method(); 
      } 
      else{  
       $attribute = split("get",$name); 
       if(count($attribute)==2){ 
        $attribute = strtolower($attribute[1]); 
        if(isset($this->$attribute)){ 
         return ($this->$attribute); 
        } 
       }else{ 
        $attribute = split("set",$name); 
        if(count($attribute)==2){ 
         $attribute = strtolower($attribute[1]); 
         if(isset($this->$attribute) && count($arguments)==1){ 
          $this->$attribute=$arguments[0]; 
         }else{ 
          die("$name number of arguments error: ".join($arguments,",")); 
         } 
        }else{ 
         die("$name doesn't exist!"); 
        }    
       }   
      } 
     } 


    } 

    echo "<pre>"; 
    $m = new Modelo(); 
    print_r(
     array(
      "objetct"=>$m 
      ,"getAttr1"=>$m->getAttr1() 
      ,"getAttr2"=>$m->getAttr2() 
     ) 
    ); 
    echo "setAttr1\n"; 
    $m->setAttr1("by set method"); 
    print_r(
     array(
      "objetct"=>$m 
      ,"getAttr1"=>$m->getAttr1() 
      ,"getAttr2"=>$m->getAttr2() 
     ) 
    ); 

    ?> 
+0

Vielen Dank, aber wie funktioniert die Codevervollständigung in Eclipse oder Netbeans in diesem Fall? – user1476490

0

Wie bereits erwähnt, ist es ziemlich seltsam, dass Ihre Klasse sollte so viele Eigenschaften haben. Es kann jedoch manchmal (ziemlich selten) passieren. Aber normalerweise sollten diese Eigenschaften eine Art von Verknüpfung haben: Sie können sie also in einer Hashmap und nicht in einer Eigenschaft speichern. Dann hast du nur eine Methode als Getter gebraucht.

Jetzt wird es sicherlich mehr Ressourcen verbrauchen, wahr. Wie für die automatische Vervollständigung, Konstanten verwenden: Sie geben Sie einfach so etwas wie:

$my_class->getFromHashMap($parameter) 

Und wenn Ihre Parameter eingeben, erhalten Sie die Konstante verwenden, wie es in der Klasse gespeichert ist: hier sollte die zur automatischen Vervollständigung der Lage zu helfen Sie.

+0

Ja, ich habe derzeit alle Eigenschaften in einem assoziativen Array, aber das ist nicht klar für den Endbenutzer (Entwickler), wie man sie alle benutzt, also muss ich Codevervollständigung und Dokumentationskommentare verwenden und den Code durch Validieren von Daten verbessern wenn der Benutzer die Variable einstellt. Hash-Map ist eine gute Lösung, aber dies wird zu anderen möglichen Problemen führen (ein Entwickler kann den Namen des Parameters falsch eingeben, ich kann Refactoring nicht verwenden, wenn ich einen Parameter umbenennen möchte usw.)) – user1476490

+0

Abgesehen von der Datenvalidierung sollte die Verwendung von Konstanten als Schlüssel für Ihre hashmap den größten Teil des Problems, das Sie beschreiben, lösen (und Sie können sogar verhindern, dass in Ihren Setter ein Schlüssel verwendet wird, der nicht in Ihren Konstanten definiert ist). – Raveline

0

Um die Eigenschaften Ihrer Klasse zu machen, die nur durch IDE von magischen Methoden umgesetzt werden highlited @property PHPDoc @property-Tag verwenden, wie folgt aus:

<?php 
/** 
* @property int id Blog post ID 
* @property string title Blog post Title 
*/ 
class Post { 

} 

Mehr auf PHPDoc‘@property hier: http://manual.phpdoc.org/HTMLSmartyConverter/PHP/phpDocumentor/tutorial_tags.property.pkg.html

Wie für andere Fragen in Frage gestellt - Karoly Horvath 'Kommentar deckt vollständig diese PHP OOP a lot of setters, getters.

0

Sie konnten dieses versuchen:

Merkmal get_set {

public function set($what, $value) 
{ 
    $this->{$what} = $value; 
} 

public function get($what) 
{ 
    return $this->{$what}; 
} 

}

Es wird auf öffentlichen und geschützten Variablen arbeiten. Sie können hinzufügen, wenn (! Isset ($ this -> {$ was}) error()