Ich möchte ein Modul (Framework-spezifisch) schreiben, das Facebook PHP-sdk ( Ссылка ) umschließt und erweitert ). Mein Problem ist - wie man Klassen auf eine nette Art organisiert.
Also ins Detail gehen - Facebook PHP-SDK besteht aus zwei Klassen:
Jetzt habe ich einige Funktionen hinzuzufügen:
Ich weiß, dass etwas sehr falsch gelaufen ist, weil ich zu viel Vererbung habe, die nicht sehr normal aussieht. Alles in einer "komplexen Extension" -Klasse zu verpacken, scheint auch zu viel. Ich denke, ich sollte nur wenige Klassen zusammen arbeiten lassen - aber ich bekomme Probleme wie: Wenn die Cache-Klasse die Methode BaseFacebook :: api () nicht wirklich erweitert und überschreibt, können Kurzschreib- und Authentifizierungsklassen das Caching nicht verwenden.
Vielleicht wäre hier eine Art Muster richtig? Wie würden Sie diese Klassen und ihre Abhängigkeiten organisieren?
BEARBEITEN 04.07.2012
Bits des Codes, die sich auf das Thema beziehen:
So ist die Basisklasse von Facebook PHP-sdk:
%Vor%Normalerweise erweitert Facebook-Klasse es, und implements diese abstrakten Methoden. Ich ersetzte es durch meine Substitute - Facebook_Session-Klasse:
%Vor%Ok, dann erweitere ich das mehr mit Methoden und Konfigurationsvariablen:
%Vor%Ich bin mir nicht sicher, ob das für eine einzelne Klasse nicht zu viel ist (Autorisierung / Kürzel Methoden / Konfiguration). Dann kommt noch ein erweiterter Layer - Cache:
%Vor%Das funktioniert jetzt ziemlich gut. Neue Instanz von Facebook_Cache gibt mir alle Funktionen. Shorthand Methoden von Facebook_Custom verwenden Caching, da Facebook_Cache die api () Methode überschreibt. Aber hier ist, was mich stört:
Also, das funktioniert wieder, aber ich frage nur nach Mustern / Wegen, dies auf eine sauberere und intelligentere Art und Weise zu tun.
Hilfsfunktionen wie das Caching werden normalerweise als Dekorator implementiert (was ich bereits erwähnt habe in einem anderen Kommentar). Decorators funktionieren am besten mit Interfaces, also würde ich damit beginnen, eines zu erstellen:
%Vor% Halten Sie es einfach, fügen Sie nichts hinzu, was Sie nicht extern benötigen (z. B. setPersistentData
). Wickeln Sie dann die vorhandene Klasse BaseFacebook
in Ihre neue Schnittstelle:
Jetzt ist es einfach, einen Caching-Decorator zu schreiben:
%Vor%Und dann:
%Vor% Sowohl $fb
als auch $cachingFb
geben die gleiche FacebookService
Schnittstelle frei - so können Sie wählen, ob Sie zwischenspeichern möchten oder nicht, und der Rest des Codes wird sich überhaupt nicht ändern.
Wie für Ihre Facebook_Custom
-Klasse, ist es gerade eine Reihe von Hilfsmethoden; Sie sollten es in eine oder mehrere unabhängige Klassen einteilen, die FacebookService
umschließen und spezifische Funktionen bereitstellen. Einige Anwendungsfälle:
Es ist tatsächlich zu viel Vererbung. Sieht aus wie ein Job für Fassade Designmuster. Verwenden Sie Komposition statt Vererbung, um mehr Flexibilität zu haben. Delegieren Sie alle Methoden, die Sie für geeignete Objekte verwenden.
Wenn sich beispielsweise eine der zugrunde liegenden Klassen ändert, können Sie einfach Ihre Methoden ändern, um sie an die Änderungen anzupassen, und Sie müssen sich keine Sorgen darüber machen, die übergeordneten Methoden zu überschreiben.
Im Allgemeinen ja, es ist keine gute Idee, einer Klasse mehrere Verantwortlichkeiten zuzuweisen. Hier würde die Verantwortung der Klasse darin bestehen, eine externe API darzustellen.
Ich habe so etwas für yahoo sdk gemacht, lass es mich sagen, probier es aus:)
Nehmen wir an, Facebook ist die Klasse in SDK, die Sie für alle Methodenaufrufe verwenden. Sie können eine neue Klasse erstellen (wie es Ihre Rahmenarbeit zulässt) und eine Variable der Klasse der Instanz der Facebook-Klasse zuweisen.
Verwenden Sie __call () für alle Methoden von Facebook und fügen Sie Ihre Kunden in die Wrapper-Klasse ein. Für alle undefinierten Methoden wird es in die Facebook-Klasse übertragen und es gibt keinerlei Vererbung. Es hat für mich funktioniert. Hoffe es hilft:)
%Vor%bearbeitet:
Sie müssen nicht mehrere Wrapper für mehr als eine Klasse erstellen, die ausgeführt werden können, Sie müssen nur auf die Methodenaufrufzeit achten, müssen den Variablennamen, der die Instanz der eingepackten Klasse enthält, suffixieren.
%Vor%Ich denke, Repository-Design-Muster werden in dieser Situation besser sein. Obwohl ich nicht von PHP bin, aber nach Oops sollte es dein Problem lösen ..