Vererbungsersatz auf mehreren Ebenen

8

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:

  • BaseFacebook - abstrakte Klasse mit all den Sachen, die sdk macht
  • Facebook - erweitert BaseFacebook und implementiert abstrakte Persistenzmethoden im Zusammenhang mit der Standardsitzung

Jetzt habe ich einige Funktionen hinzuzufügen:

  • Facebook-Klassensubstitution, integriert mit Framework-Session-Klasse
  • shorthand-Methoden, die api-Aufrufe ausführen, verwende ich meistens (über BaseFacebook :: api ()),
  • Autorisierungsmethoden, also muss ich diese Logik nicht jedes Mal neu schreiben,
  • Konfiguration, aus Rahmenklassen aufgesaugt, als Params übergeben
  • Caching, integriert mit Framework-Cache-Modul

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:

  • Ich denke, es ist zu viel Erbe.
  • Es ist alles sehr eng gekoppelt - wie sehen, wie ich 'Facebook_Custom :: api' anstelle von 'Eltern: api' angeben musste, um die api () - Methodenschleife in der Facebook_Cache-Klasse zu vermeiden.
  • Insgesamt Unordnung und Hässlichkeit.

Also, das funktioniert wieder, aber ich frage nur nach Mustern / Wegen, dies auf eine sauberere und intelligentere Art und Weise zu tun.

    
Luigi 30.06.2012, 14:34
quelle

4 Antworten

2

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:

%Vor%

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:

%Vor%     
casablanca 15.07.2012, 10:52
quelle
2

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.

    
siimsoni 10.07.2012 02:55
quelle
2

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%     
Rupesh Patel 12.07.2012 12:36
quelle
0

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 ..

    
Dr. Rajesh Rolen 30.06.2012 17:07
quelle

Tags und Links