Konvertieren von prozeduralem PHP in objektorientiertes PHP

8

Ich habe derzeit eine ziemlich große Anwendung, die vollständig mit prozeduralem PHP geschrieben ist. Ich versuche, meine PHP-Erfahrung zu verbessern und einen Großteil meiner Anwendung mit objektorientierten Techniken zu rekodieren.

Es gibt viele Bereiche, in denen OOP die Menge an Code reduzieren und das Lesen erleichtern kann. Ich habe jedoch ein paar Fragen.

1) Ich verstehe, dass eine Klasse als Blaupause für eine beliebige Anzahl von Objekten verwendet wird, aber jede Klasse nur ein Objekt repräsentiert, niemals mehr als eins. Eine Klasse könnte also einen Spieler repräsentieren, aber niemals mehrere Spieler.

2) Da ich einige verschiedene Klassen haben werde, benutze ich eine "Loader" Klasse, um sie alle mit spl_autoload_register zu laden oder benutze einfach spl_autoload_register in der Programmdateien für meine Anwendung?

Bearbeiten: Also wäre mein Autoloader eine Klasse, die ich dann eine Instanz erstellen würde, um das Autoloading zu starten oder einfach eine PHP-Datei mit der Funktion und dem spl_autoload_register, die ich einfügen würde, um die Wiederholung zu vermeiden Code in mehreren Dateien?

3) Einige meiner Klassen sind von anderen Klassen abhängig. Ich habe das noch nie zuvor gesehen, daher kenne ich die Antwort ehrlich nicht. Wenn ich alle Klassen in meine Hauptprogrammdatei einbeziehe, aber meine Player-Klasse nicht die Klasse enthält, die sie benötigt, wird die Player-Klasse arbeiten, da das Hauptprogramm die Klasse enthält, von der der Player abhängt an?

Bearbeiten: Obwohl eine Klasse ein Objekt vom Typ Player instanziieren kann und die Player-Klasse nicht direkt in dieser Klasse enthalten ist, funktioniert sie trotzdem, weil die Controller-Klasse / em> die Player-Klasse einschließen?

4) Es gibt mehrere Fälle, in denen ich an den von mir erstellten Objekten arbeiten muss. Ich frage mich, wie ich das machen soll. Zum Beispiel muss ich in meiner Player-Klasse manchmal etwas von einem Player an den anderen Player senden. Implementiere ich also eine statische Methode in der Player-Klasse, die zwei Player als Parameter akzeptiert und die Übertragung durchführt oder etwas anderes mache?

Bearbeiten: Okay, vermeiden Sie statische Methoden. Jetzt habe ich ein ernstes Problem: Ich habe Methoden, die in meiner Anwendung mehrfach ausgeführt werden, aber ich kann sie nicht als statische Methoden implementieren. Soll ich sie als Instanzmethoden implementieren? Zum Beispiel, Senden von einem Player zu einem anderen. Würde ich eine Instanzmethode erstellen, die ein Player-Objekt akzeptiert und entweder an oder an sendet?

5) Ich habe viele Methoden, die nicht wirklich zu einer Instanz einer Klasse gehören, noch sind sie als statische Methoden wirklich geeignet. Sollten diese in ihrer eigenen Klasse als statische Methoden wie Common oder ähnlich deklariert werden? Was macht man in dieser Situation in der Praxis?

Bearbeiten: Würden diese Methoden zu der spezifischen Anwendungsdatei gehören, für die sie verwendet werden, oder vielleicht in einer eigenen Datei "functions.php" gespeichert werden?

6) Ich würde gerne lernen, wie man Namespaces verwendet, aber mein Code wird niemals von anderen benutzt werden und ich werde nie den Code von jemand anderem in meiner Anwendung verwenden. Sind Namespaces eine unnötige Ergänzung in meiner Anwendung oder wäre es eine gute Idee zu lernen, wie man sie benutzt? Unabhängig davon, hat eine Anwendung einen Namespace (den Anwendungsnamen?) Oder gehört jede Klasse zu ihrem eigenen Namespace?

7) Ist es schließlich üblich, eine Klasse für Datenbankverbindungen und eine Klasse für Netzwerkmethoden zu haben? Meine Anwendung benötigt beides. Ich denke, das Hauptproblem bei der Konvertierung meines Codes, objektorientierte Techniken zu verwenden, besteht darin, zu bestimmen, welche Methoden wo platziert werden sollen, da sie sich alle in einer einzigen monolithischen Datei befinden.

Vielen Dank für Ihre Hilfe und Ihren Einblick.

    
Steffan Long 14.03.2013, 22:16
quelle

3 Antworten

2
  

1) Ich verstehe, dass eine Klasse als Bauplan für eine beliebige Anzahl von Objekten verwendet wird, aber jede Klasse nur ein Objekt repräsentiert, niemals mehr als eins. Eine Klasse könnte also einen Spieler repräsentieren, aber niemals mehrere Spieler.

Normalerweise haben Sie auch Klassen, die Sammlungen von Objekten darstellen, z. eine Klasse "Spieler", mit der ein einzelner Spieler aus der Sammlung aller Spieler abgerufen werden kann:

%Vor%
  

2) Da ich einige verschiedene Klassen haben werde, verwende ich eine "Loader" -Klasse, um sie alle mit spl_autoload_register zu laden, oder verwende ich einfach spl_autoload_register in den Programmdateien für meine Anwendung?

Das hängt ziemlich von der Komplexität Ihres Projekts ab. Eine einfache Autoloader-Funktion ist normalerweise ausreichend, aber Sie können sich den Zend Framework Autoloader ansehen Klasse .

  

3) Einige meiner Klassen sind von anderen Klassen abhängig. Ich bin dem noch nie begegnet, also kenne ich die Antwort ehrlich nicht. Wenn ich alle Klassen in meine Hauptprogrammdatei einbeziehe, aber meine Spielerklasse nicht die Klasse enthält, die sie benötigt, wird die Spielerklasse funktionieren, da das Hauptprogramm die Klasse enthält, von der der Spieler abhängt?

Ja. Beim Autoloading müssen Sie sich darüber jedoch keine Gedanken machen. Wenn Sie kein Autoloading verwenden, sollten Sie die erforderlichen Klassen in die Datei aufnehmen, die die Klasse definiert (indem Sie require_once() verwenden, um zu vermeiden, dass dieselbe Datei mehr als einmal eingeschlossen wird).

  

4) Es gibt mehrere Fälle, in denen ich an den Objekten arbeiten muss, die ich erstelle. Ich frage mich, wie ich das machen soll. Zum Beispiel muss ich in meiner Player-Klasse manchmal etwas von einem Player an den anderen Player senden. Implementiere ich also eine statische Methode in der Player-Klasse, die zwei Player als Parameter akzeptiert und die Übertragung durchführt oder etwas anderes mache?

Statische Methoden sind fast immer der falsche Ansatz. Normale Verfahren gehören zu einer Instanz (d. H. Der spezifische Spieler) und statische Methoden gehören zu der Klasse, d. H. Der allgemeinen "Idee" eines Spielers. Wenn Sie Daten von einem Player auf einen anderen übertragen müssen, implementieren Sie dies wie folgt:

%Vor%
  

5) Ich habe viele Methoden, die nicht wirklich zu einer Instanz einer Klasse gehören, noch sind sie als statische Methoden wirklich geeignet. Sollten diese in ihrer eigenen Klasse als statische Methoden wie Common oder ähnlich deklariert werden? Was macht man in dieser Situation in der Praxis?

Ich kann das nicht vernünftig beantworten. Allerdings gibt es in PHP noch einfache Funktionen, die für solche Fälle die beste Methode zu sein scheinen. Aber wenn Sie OOP richtig machen, werden Sie höchstwahrscheinlich nie auf solche Probleme stoßen. Es ist normalerweise ein Problem mit Ihrem Klassendesign, das Sie dazu bringt, dass diese Methoden zu keinem Objekt gehören.

  

6) Ich würde gerne lernen, wie man Namespaces benutzt, aber mein Code wird niemals von anderen benutzt werden und ich werde nie den Code von jemand anderem in meiner Anwendung verwenden. Sind Namespaces eine unnötige Ergänzung in meiner Anwendung oder wäre es eine gute Idee zu lernen, wie man sie benutzt? Unabhängig davon, hat eine Anwendung einen Namespace (den Anwendungsnamen?) Oder gehört jede Klasse zu ihrem eigenen Namespace?

Namespaces sind großartig, aber Ihr Code wird wahrscheinlich ohne sie gut ausgehen. Da Namespaces verschachtelt werden können, haben Sie normalerweise einen Namespace auf oberster Ebene und Unternamespaced pro Komponente.

  

7) Ist es schließlich üblich, eine Klasse für Datenbankverbindungen und eine Klasse für Netzwerkmethoden zu haben? Meine Anwendung benötigt beides. Ich denke, das Hauptproblem bei der Konvertierung meines Codes, objektorientierte Techniken zu verwenden, besteht darin, zu bestimmen, welche Methoden wo platziert werden sollen, da sie sich alle in einer einzigen monolithischen Datei befinden.

Dies hängt davon ab, wie Sie Ihre aktuelle Situation modellieren. Wenn Datenbankverbindung und "Netzwerk" zwei verschiedene Dinge für Sie sind, sind zwei Klassen der Weg zu gehen.

    
Niko 14.03.2013, 22:33
quelle
4
  

1) Ich verstehe, dass eine Klasse als Bauplan für eine beliebige Anzahl von Objekten verwendet wird, aber jede Klasse nur ein Objekt repräsentiert, niemals mehr als eins. Eine Klasse könnte also einen Spieler repräsentieren, aber niemals mehrere Spieler.

Eine Klasse repräsentiert nichts, weil Sie, wie Sie richtig sagten, nur eine Blaupause für eine beliebige Anzahl von Objekten ist. Sie können mehrere Instanzen (Objekte) derselben Klasse haben, die mehrere Spieler repräsentieren.

  

2) Da ich einige verschiedene Klassen haben werde, verwende ich eine "Loader" -Klasse, um sie alle mit spl_autoload_register zu laden, oder verwende ich einfach spl_autoload_register in den Programmdateien für meine Anwendung?

Ohne zu wissen, was Sie unter "Programmdateien für meine Anwendung" verstehen, sage ich ja. Benutze einen Autoloader, weil es einfach funktioniert und du dich nicht um require_* kümmern musst.

  

3) Einige meiner Klassen sind von anderen Klassen abhängig. Ich habe das noch nie zuvor gesehen, daher kenne ich die Antwort ehrlich nicht. Wenn ich alle Klassen in meine Hauptprogrammdatei einbeziehe, aber meine Spielerklasse nicht die Klasse enthält, die sie benötigt, wird die Spielerklasse funktionieren, da das Hauptprogramm die Klasse enthält, von der der Spieler abhängt?

Sie möchten nicht alle Klassen laden, sondern nur die Klassen, die Sie verwenden möchten. Bei der Verwendung eines Autoloaders müssen Sie sich ebenfalls keine Sorgen machen. Aber sobald eine Klasse geladen ist, kann sie in der gesamten Anwendung instanziiert werden.

Normalerweise möchten Sie den Autoploader in der Bootstrap-Phase der Anwendung starten .

  

4) Es gibt mehrere Fälle, in denen ich an den Objekten arbeiten muss, die ich erstelle. Ich frage mich, wie ich das machen soll. Zum Beispiel muss ich in meiner Player-Klasse manchmal etwas von einem Player an den anderen Player senden. Implementiere ich also eine statische Methode in der Player-Klasse, die zwei Player als Parameter akzeptiert und die Übertragung durchführt oder etwas anderes mache?

Vermeiden Sie statische Methoden in OOP PHP. Es wird fast nie benötigt. Man könnte darüber nachdenken, eine andere Klasse zu haben, die sich wie ein Pool von Spielern verhält, der sich um das "Senden von Daten" von einem Spieler zum anderen kümmert.

Es spielt also keine Rolle, wo die Datei mit der Klasse enthalten ist, solange sie passiert, bevor versucht wird, sie zu instanziieren.

  

5) Ich habe viele Methoden, die nicht wirklich zu einer Instanz einer Klasse gehören, noch sind sie als statische Methoden wirklich geeignet. Sollten diese in ihrer eigenen Klasse als statische Methoden wie Common oder ähnlich deklariert werden? Was macht man in dieser Situation in der Praxis?

Auch hier bitte keine statischen Methoden verwenden. Wenn Sie sie in einer anderen Klasse verwenden, erschweren Sie nur das Unit-Testen Ihrer Klassen und Sie führen versteckte Abhängigkeiten ein. Meiner Erfahrung nach ist es nie so, dass es eine einzige Methode irgendwo für etwas gibt. Vielleicht machst du Methoden zu viel.

Aber das ist schwer zu sagen, wenn Sie nur Ihre Frage lesen. Vielleicht kannst du ein Beispiel in einem Kommentar geben?

  

6) Ich würde gerne lernen, wie man Namespaces benutzt, aber mein Code wird niemals von anderen benutzt werden und ich werde nie den Code von jemand anderem in meiner Anwendung verwenden. Sind Namespaces eine unnötige Ergänzung in meiner Anwendung oder wäre es eine gute Idee zu lernen, wie sie verwendet werden?

Namespacing in PHP ist über Strukturierung. Obwohl niemand sonst Ihren Code verwenden wird, müssen Sie sich keine Gedanken darüber machen, den gleichen Namen für eine Klasse irgendwo zu verwenden. Das wird passieren, wenn die Anwendung früher oder später größer wird.

  

Unabhängig davon, hat eine Anwendung einen Namespace (den Anwendungsnamen?) oder gehört jede Klasse zu ihrem eigenen Namespace?

Ich folge häufig PSR-0 , wenn es dazu kommt zu Namespaces.

  

7) Ist es schließlich üblich, eine Klasse für Datenbankverbindungen und eine Klasse für Netzwerkmethoden zu haben? Meine Anwendung benötigt beides. Ich denke, das Hauptproblem bei der Konvertierung meines Codes für die Verwendung objektorientierter Techniken besteht darin, zu bestimmen, welche Methoden wo platziert werden sollen, da sie sich alle in einer einzigen Datei befinden.

Behalte einfach das Prinzip Prinzip der einzelnen Verantwortlichkeit im Hinterkopf und generell SOLID .

Ich schlage auch vor, diese zu sehen und sie so lange zu beobachten, bis Sie es verstehen.

>     
PeeHaa 14.03.2013 22:30
quelle
1
  1. Eine PlayerCollection wäre eine gültige Klasse. Ein Objekt davon ist natürlich eine Sammlung von mehreren Spielern.

  2. Verwende spl_autoload_register, Punkt. Am besten folgen Sie dem PSR-0 Standard und verwenden Sie ein beliebiges PSR- 0 kompatibler existierender Autoloader (zB Symfony Loader )

  3. Es wird funktionieren. Da Sie jedoch einen Autoloader verwenden (siehe 2.), müssen Sie sich nicht darum kümmern, überhaupt Klassen einzubinden

  4. Das Senden einer Nachricht von Player 1 an Player 2 kann leicht mit dem Aufruf einer Methode von Player 2 in Player 1 übersetzt werden. "Senden von Dingen" und "Arbeiten an Objekten" können jedoch viele Dinge bedeuten : es kommt darauf an. Aber im Allgemeinen ist es ein guter Rat, statische Methoden zu vermeiden .

  5. Das klingt nach Vorgehensweisen. Es tut mir leid, aber ich kann Ihnen hier keine eindeutige Antwort geben, Sie müssen die Prinzipien des objektorientierten Designs kennen und verstehen, um sie anzuwenden. Es gibt einige Standardliteratur und viele nützliche Ressourcen im Internet. Auch das Lernen anhand eines Beispiels könnte nützlich sein (schauen Sie sich andere OO-Anwendungen und das Framework an, die auf Open Source basieren)

  6. "Hat eine Anwendung einen Namespace (den Anwendungsnamen?) oder gehört jede Klasse zu ihrem eigenen Namespace?" - Die Antwort liegt dazwischen. Namespaces sind nützlich, um Dinge zusammen zu gruppieren, die zusammenarbeiten, und sie sind nützlich, unabhängig davon, wer den Code verwendet oder sieht.

  7. Erste Regel des objektorientierten Designs: Eine Klasse, eine Verantwortung.

Fabian Schmengler 14.03.2013 22:31
quelle