Strategie zum Umschreiben von Klassen

7

[TL: DR]
Ich habe Core_Class_Aund Core_Class_B extends Core_Class_A.
Ich muss beide neu schreiben und eine gemeinsame Funktionalität hinzufügen.

Also habe ich folgendes gemacht : Custom_Class_A extends Core_Class_A.
Die Frage ist, welche von unten ich verwenden soll (Daumen hoch und Daumen runter für jeden):

  1. Custom_Class_B extends Custom_Class_A
  2. Custom_Class_B extends Core_Class_B

[Vollversion] Ich arbeite an einer Erweiterung, die der geschichteten Navigation einen neuen Filter hinzufügt: auf Lager / nicht auf Lager (Sie werden ihn in einigen Tagen öffentlich sehen).
Der Code, bisher kein großes Problem, die Strategie ... Ich habe meine Zweifel.
Da es im Bereich der geschichteten Navigation keine Ereignisse gibt, mit denen ich meinen neuen Filter hinzufügen kann, musste ich 2 Blöcke neu schreiben: Mage_Catalog_Block_Layer_Viewund Mage_CatalogSearch_Block_Layer. (Wenn jemand bessere Ideen hat, teilen Sie diese bitte mit, dies ist jedoch nicht Gegenstand der Frage.)

Für das habe Mage_Catalog_Block_Layer_Viewich es so gemacht, wie Vinai es mir indirekt gedacht hat ( siehe diese Rezension über eine der Erweiterungen von Vinai ).
Ich habe die Methoden hinzugefügt, die ich umschreiben wollte, habe gerade parent::methodName()ein Ereignis aufgerufen und gesendet, das jeder beobachten kann.

Hier ist ein Beispiel für die Methode _initBlocks. Meine neue Methode sieht folgendermaßen aus:

protected function _initBlocks()
{
    parent::_initBlocks(); //call the parent method
    //dispatch an event that I can observe and add my logic.
    Mage::dispatchEvent('catalog_layer_view_init_blocks', array('block' => $this));
}

Aber das Problem kommt für Mage_CatalogSearch_Block_Layer. Dieser Block erweitert den ersten Mage_Catalog_Block_Layer_View.

Zum Beispiel muss ich die Methode _initBlockswie oben gezeigt neu schreiben . Das Problem ist jedoch, dass Mage_CatalogSearch_Block_Layeres keine eigene _initBlocksMethode gibt. Es wird die aus der übergeordneten Klasse verwendet Mage_Catalog_Block_Layer_View.
Was mache ich hier?
Sollte ich das gleiche System wie oben verwenden oder meine neue Klasse [Namespace]_[Module]_Block_Catalogsearch_Layermeine eigene Klasse erweitern lassen, die ich zum Umschreiben erstellt habe, Mage_Catalog_Block_Layer_Viewund einfach die verschiedenen Methoden von kopieren Mage_CatalogSearch_Block_Layer?

Marius
quelle
Dies ist nicht meinungsbasiert, wenn Sie die Vor- und Nachteile für jeden Ansatz angeben.
Marius
Eigenschaften wären
meiner
@ Philwinkle. Ich stimme zu, aber es gibt einen Fehler in Ihrem bösen Plan. Wie ich Flyingmana unten für eine Antwort erklärt habe, muss dies auch für PHP 5.3 funktionieren.
Marius

Antworten:

12

Nachdem Sie sich Ihr Problem mit diesem sehr einfachen Klassenvererbungsdiagramm angesehen haben (entschuldigen Sie übrigens die schlechte Zeichnung), ist es besser, mit dem von Ihnen gewählten Ansatz fortzufahren und ihn zu erstellen Custom_Class_B extends Core_Class_B.

Erbe

In Bezug auf diese Zeichnung scheint es mir offensichtlich, dass Sie die erweiterte Funktionalität von Core_Class_BVersion 1 (V1) vermissen werden und diese Funktionalität aus dem Core kopieren müssten, was kein guter Ansatz ist.

V2 ist in diesem Fall transparenter.

Anna Völkl
quelle
3
+1 für die tolle Antwort und die Zeichnung hilft nur, sie zu verkaufen :)
Philwinkle
5

Erstens sollten Sie niemals einen Ansatz wählen, bei dem Sie Methoden einer anderen Klasse kopieren müssen, wenn Sie andere Möglichkeiten haben. Sobald sie sich ändern, erhalten Sie Aktualisierungsprobleme und ein Arbeitsprotokoll.

Sie zu erweitern und Ihre eigene Methode erneut zu implementieren, ist die bessere Wahl. Natürlich sollten Sie hier nicht noch einmal kopieren. Die Verwendung eines Beobachters ist ein guter Weg, um Code-Duplikationen zu vermeiden. Ein weiterer Weg wäre die Verwendung der PHP TRAIT-Funktion, mit der Code zwischen Klassen ausgetauscht werden kann.

Flyingmana
quelle
Leider kann ich keine Eigenschaften verwenden, da dies auch auf PHP 5.3 funktionieren sollte. Außerdem muss in meinem Fall ein Teil des Codes dupliziert werden. Entweder dupliziere ich den Code aus der Kernklasse oder aus dem Code, den ich in Schritt 1 erstellt habe, wenn ich die erste Klasse neu schreibe. Aber ich verstehe, was du meinst. Ich denke, ich sollte keinen Code aus dem Kern duplizieren. Besser mein eigener Code, weil ich die Kontrolle darüber habe. Vielen Dank.
Marius