Ist dies ein vernünftiger Weg, um Getter / Setter in einer PHP-Klasse zu behandeln?

8

Ich werde etwas mit dem Format dieser Frage versuchen, und ich bin sehr offen für Vorschläge über einen besseren Weg, damit umzugehen.

Ich wollte nicht einfach einen Haufen Code in der Frage ablegen, also habe ich den Code für die Klasse unter refactormycode veröffentlicht.

Basisklasse für die einfache Handhabung von Klasseneigenschaften

Mein Gedanke war, dass Leute hier entweder Codeschnipsel posten oder Änderungen an refactormycode vornehmen und Links zu ihren Refactorings zurücksenden können. Ich werde Upvotes machen und eine Antwort akzeptieren (vorausgesetzt es gibt einen klaren "Gewinner"), basierend darauf.

Jedenfalls auf die Klasse selbst:

Ich sehe viele Diskussionen über Getter / Setter-Klassenmethoden und ist es besser, einfach nur auf einfache Eigenschaftsvariablen zuzugreifen, oder sollte jede Klasse explizite get / set-Methoden haben, bla bla bla. Ich mag die Idee, explizite Methoden zu haben, falls Sie später mehr Logik hinzufügen müssen. Dann müssen Sie keinen Code ändern, der die Klasse verwendet. Aber ich hasse es, eine Million Funktionen zu haben, die so aussehen:

%Vor%

Ich bin mir sicher, dass ich nicht die erste Person bin, die das tut (ich hoffe, dass es einen besseren Weg gibt, den mir jemand vorschlagen kann).

Grundsätzlich verfügt die PropertyHandler-Klasse über eine Call-Magic-Methode. Alle Methoden, die durch __call kommen und mit "get" oder "set" beginnen, werden dann an Funktionen weitergeleitet, die Werte in einem assoziativen Array setzen oder abrufen. Der Schlüssel in das Array ist der Name der aufrufenden Methode nach get oder set. Wenn also die Methode, die in __call eingeht, "getFirstName" lautet, lautet der Array-Schlüssel "FirstName".

Ich habe __call gerne benutzt, weil es sich automatisch um den Fall kümmert, in dem die Unterklasse bereits eine "getFirstName" -Methode definiert hat. Mein Eindruck (und ich könnte falsch liegen) ist, dass die __get & amp; __set magische Methoden tun das nicht.

Hier ist ein Beispiel, wie es funktionieren würde:

%Vor%

Beachten Sie, dass PropTest nicht tatsächlich "setFirstName" - oder "getFirstName" -Methoden hat und auch PropertyHandler nicht. Es werden nur Array-Werte manipuliert.

Der andere Fall wäre, wo Ihre Unterklasse bereits etwas anderes erweitert. Da Sie in PHP keine echte Mehrfachvererbung haben können, können Sie Ihre Unterklasse dazu veranlassen, eine PropertyHandler-Instanz als private Variable zu verwenden. Sie müssen eine weitere Funktion hinzufügen, aber dann verhalten sich die Dinge genauso.

%Vor%

Beachten Sie, dass die Unterklasse eine __call-Methode hat, die alles an die PropertyHandler __call-Methode weiterleitet.

Ein anderes gutes Argument gegen die Handhabung von Getter und Setter ist, dass es sehr schwer zu dokumentieren ist.

Tatsächlich ist es im Prinzip unmöglich, ein Dokumentgenerierungstool zu verwenden, da die expliziten Methoden, die nicht dokumentiert werden sollen, nicht existieren.

Ich habe diesen Ansatz vorerst aufgegeben. Es war eine interessante Lernübung, aber ich denke, es opfert zu viel Klarheit.

    
Mark Biek 28.08.2008, 12:54
quelle

8 Antworten

5

So mache ich das:

%Vor%

Was ausgegeben wird (Zeilenumbrüche zur besseren Übersicht hinzugefügt)

%Vor%     
Pat 28.08.2008 13:06
quelle
3

@Brian

  
    
      
        

Mein Problem dabei ist, dass das Hinzufügen von "mehr Logik zu einem späteren Zeitpunkt" das Hinzufügen von pauschaler Logik für alle Eigenschaften erfordert, auf die mit dem Getter / Setter zugegriffen wird, oder die Sie verwenden, wenn Sie angeben, auf welche Eigenschaft Sie zugreifen Sie können eine bestimmte Logik anwenden.

      
    
  

Das stimmt nicht ganz. Nehmen Sie mein erstes Beispiel:

%Vor%

Nehmen wir an, dass ich eine Logik für die Validierung von FirstNames hinzufügen muss. Alles, was ich tun muss, ist eine Methode setFirstName zu meiner Unterklasse hinzufügen und diese Methode wird stattdessen automatisch verwendet.

%Vor%
  
    
      
        

Ich bin einfach nicht zufrieden mit den Einschränkungen, die PHP bei impliziten Zugriffsmethoden hat.

      
    
  

Ich stimme völlig zu. Ich mag die Python-Art, dies zu handhaben (meine Implementierung ist nur eine ungeschickte Abzocke davon).

    
Mark Biek 28.08.2008 14:14
quelle
2

Ja, das stimmt, die Variablen müssen manuell deklariert werden, aber ich finde das besser, da ich einen Tippfehler im Setter befürchte

%Vor%

generiert automatisch eine neue Eigenschaft (FristName anstelle von FirstName), die das Debuggen erschweren wird.

    
Pat 28.08.2008 13:14
quelle
1

Ich mag Methoden, anstatt nur öffentliche Felder zu verwenden, aber mein Problem mit der PHP-Standardimplementierung (mit __get () und __set ()) oder Ihrer benutzerdefinierten Implementierung besteht darin, dass Sie keine Getter und Setter auf a einrichten Pro-Objekt-Basis. Mein Problem dabei ist, dass das Hinzufügen von "mehr Logik später" erfordert, dass Sie pauschale Logik hinzufügen, die für alle Eigenschaften gilt, auf die mit dem Getter / Setter zugegriffen wird oder die Sie verwenden, wenn Sie Anweisungen ändern, um zu ermitteln, auf welche Eigenschaft Sie zugreifen spezifische Logik.

Ich mag Ihre Lösung, und ich applaudiere Ihnen dafür - ich bin einfach nicht zufrieden mit den Einschränkungen, die PHP hat, wenn es um implizite Zugriffsmethoden geht.

    
Brian Warshaw 28.08.2008 13:14
quelle
1

@Mark

Aber selbst Ihre Methode erfordert eine neue Deklaration der Methode, und sie hat den Vorteil, dass sie in eine Methode eingefügt werden kann, so dass Sie mehr Logik hinzufügen können, denn um mehr Logik hinzuzufügen, erfordert die altmodische Deklaration der Methode , sowieso. In ihrem Standardzustand (wo sie beeindruckend ist, was sie erkennt / tut), bietet Ihre Technik keinen Vorteil (in PHP) gegenüber öffentlichen Feldern. Sie beschränken den Zugriff auf das Feld, aber geben Carte Blanche durch Zugriffsmethoden, die keine eigenen Einschränkungen haben. Ich bin mir nicht bewusst, dass unkontrollierte explizite Accessoren einen Vorteil gegenüber öffentlichen Feldern in jeder Sprache bieten, aber die Leute können und sollten sich frei fühlen, mich zu korrigieren, wenn ich falsch liege.

    
Brian Warshaw 28.08.2008 14:28
quelle
0

Ich habe dieses Problem schon immer mit einem __call behandelt, der in vielen meiner Klassen so ziemlich mit einem Kesselblech-Code endet. Es ist jedoch kompakt und verwendet die Reflektionsklassen, um nur Getter / Setter für Eigenschaften hinzuzufügen, die Sie bereits festgelegt haben (es werden keine neuen hinzugefügt). Wenn Sie den Getter / Setter explizit hinzufügen, werden komplexere Funktionen hinzugefügt. Es wird erwartet,

zu sein

Code sieht so aus:

%Vor%

Hinzufügen zu einer Klasse, in der Sie Standardeigenschaften wie folgt deklariert haben:

%Vor%

Die Reflexionsklasse kann Ihrem Vorschlag etwas hinzufügen. Saubere Lösung @Mark.

    
reefnet_alex 28.08.2008 15:02
quelle
0

Vor Kurzem habe ich darüber nachgedacht, Getter und Setter so zu behandeln, wie Sie es vorgeschlagen haben (der zweite Ansatz war mein Favorit, dh das private $ reps-Array), aber ich habe es verworfen, weil es in meiner App nicht geklappt hätte.

Ich arbeite an einer ziemlich großen SoapServer-basierten Anwendung und die Soap-Schnittstelle von PHP 5 injiziert die Werte, die via Soap übertragen werden, direkt in die zugehörige Klasse, ohne sich um bestehende oder nicht existierende Eigenschaften in der Klasse zu kümmern. p>     

Dan Soap 06.01.2009 20:21
quelle
0

Ich kann nicht helfen, meine 2 Cent hineinzulegen ...

Ich habe mich dafür entschieden, __get und __set in diesem Herrenhaus zu verwenden (ähnlich wie es die Doktrin tut) ), dann nur Zugriff auf die Eigenschaften über die $obj->var außerhalb der Klasse. Auf diese Weise können Sie die Funktionalität nach Bedarf außer Kraft setzen, anstatt eine große Funktion __get oder __set zu erstellen oder __get und __set in den untergeordneten Klassen zu überschreiben.

    
SeanJA 17.04.2010 15:01
quelle

Tags und Links