Ich begann damit, eine Frage zu formulieren: "Was ist der beste Weg, Komponententests an einem Konstruktor durchzuführen (z. B. __construct () in PHP5)? Aber beim Lesen der zugehörigen Fragen sah ich mehrere Kommentare Ich schlage vor, dass das Setzen von Member-Variablen oder die Ausführung komplizierter Operationen im Konstruktor keine Nos sind.
Der Konstruktor für die fragliche Klasse nimmt hier einen Parameter, führt einige Operationen für ihn durch (stellt sicher, dass er einen Sniff-Test besteht und wandelt ihn bei Bedarf um) und speichert ihn dann in einer Member-Variable.
Ich dachte, die Vorteile wären:
1) dieser Client-Code wäre immer sicher, einen Wert dafür zu haben Elementvariable jedesmal wenn ein Objekt dieser Klasse wird instanziiert und
2) speichert einen Schritt im Client-Code (Eine davon könnte denkbar sein verpasst), z. B.
%Vor%wenn wir das einfach machen könnten
%Vor%und damit fertig sein.
Ist das ein Nein? Wenn ja warum?
Das kommt in C ++ - Diskussionen ziemlich oft vor, und die allgemeine Schlussfolgerung, zu der ich gekommen bin, war folgende:
Wenn ein Objekt keine externen Ressourcen erhält, müssen die Member im Konstruktor in initialisiert werden. Dazu müssen alle Arbeiten im Konstruktor ausgeführt werden.
Wenn ein Objekt Ressourcen erwirbt, die es steuern kann, können in dem Konstruktor zugewiesen werden:
Wenn das Objekt Ressourcen erwirbt, die nicht vollständig kontrolliert werden können, müssen außerhalb des Konstruktors zugewiesen werden:
Es gibt immer Ausnahmen, aber dies deckt die meisten Fälle ab.
Als Faustregel gilt, dass ein Objekt nach Abschluss des Konstruktors einsatzbereit sein sollte. Aber es gibt oft eine Reihe von Optionen, die anschließend optimiert werden können.
Meine Liste von Do's und Donts:
Natürlich keine Regeln ohne Ausnahmen. Wichtig ist, dass Sie über Ihr Design und Ihre Wahl nachdenken. Machen Sie die Verwendung von Objekten natürlich - und dazu gehört die Fehlerberichterstattung.
Konstruktoren sind für die Initialisierung des Objekts, also
%Vor%ist vollkommen akzeptabel.
Der Job eines Konstruktors besteht darin, die Invarianten einer Instanz festzulegen.
Alles was dazu nicht beiträgt, wird am besten außerhalb des Konstruktors gehalten.
Um die Testbarkeit einer Klasse zu verbessern, ist es im Allgemeinen eine gute Sache, den Konstruktor so einfach wie möglich zu halten und nur nach Dingen fragen zu lassen, die er absolut benötigt. Es gibt eine hervorragende Präsentation , die im Rahmen der "Clean Code Talks" -Serie von Google auf YouTube verfügbar ist. p>
Sie sollten es auf jeden Fall vermeiden, dass der Client anrufen muss
%Vor%Solche Sachen gehören absolut in den Konstruktor. Es ist einfach unfreundlich gegenüber dem Client-Programmierer, um sie dazu zu bringen, dies anzurufen. Es gibt eine (etwas umstrittene) Denkweise, die besagt, dass Sie Klassen schreiben sollten, so dass Objekte nie in einem ungültigen Zustand sind - und "nicht initialisiert" ist ein ungültiger Zustand.
Aus Gründen der Testbarkeit und der Leistung ist es jedoch manchmal sinnvoll, bestimmte Initialisierungen auf später im Objekt zu verschieben. In Fällen wie diesen ist faule Bewertung die Lösung.
Entschuldigung dafür, dass Java-Syntax in eine Python-Antwort geschrieben wurde, aber:
%Vor%Sie können Ihre träge Initialisierung segmentieren, so dass nur die Teile initialisiert werden, die sie benötigen. Es ist zum Beispiel üblich, dies in Gettern zu tun, nur für das, was den Wert beeinflusst, der erhalten wird.
Hängt davon ab, welche Art von System Sie zu entwerfen versuchen, aber im Allgemeinen glaube ich, dass Konstruktoren am besten dazu verwendet werden, nur den "Zustand" des Objekts zu initialisieren, aber selbst keine Zustandsübergänge auszuführen. Am besten lassen Sie einfach die Standardeinstellungen festlegen.
Ich schreibe dann eine "handle" -Methode in meine Objekte, um Dinge wie Benutzereingaben, Datenbankaufrufe, Ausnahmen, Sortierungen usw. zu behandeln. Der Grundgedanke ist, dass dies jeden Zustand, in dem sich das Objekt befindet, basierend auf externen Kräften (Benutzereingaben, Zeit usw.) handhabt. Grundsätzlich werden alle Dinge, die den Zustand des Objekts ändern und zusätzliche Aktionen erfordern, in den Objekt.
Schließlich habe ich eine Rendermethode in die Klasse eingefügt, um dem Benutzer etwas Sinnvolles zu zeigen. Dies stellt nur den Zustand des Objekts für den Benutzer dar (was auch immer das sein mag.)
__ Konstrukt ($ Argumente)
handhaben ()
render (Ausnahme $ ex = null)
Die __construct magic-Methode ist in Ordnung. Der Grund für die Initialisierung in vielen Frameworks und Anwendungen liegt darin, dass das Objekt auf eine Schnittstelle programmiert wird oder versucht, ein Singleton / getInstance-Muster zu erstellen.
Diese Objekte werden im Allgemeinen in einen Kontext oder einen Controller gezogen, und dann werden sie von anderen übergeordneten Objekten mit der allgemeinen Schnittstellenfunktionalität aufgerufen.
Sie sollten Dinge nicht in einen Konstruktor einfügen, der nur einmal ausgeführt werden soll, wenn die Klasse erstellt wird.
Um es zu erklären.
Wenn ich eine Datenbankklasse hätte. Der Konstruktor ist die Verbindung zur Datenbank Also
%Vor%Und jetzt bin ich mit der Datenbank verbunden.
Dann haben wir eine Klasse, die einige Methoden innerhalb der Datenbankklasse verwendet.
%Vor%Tags und Links php constructor oop