Private Funktion von Service überschreiben

Hallo zusammen!

Es ist ja möglich, beliebige Services, die im DI Container sind, zu erweitern (siehe hier). Ich möchte jetzt von einem Service nur eine einzige Funktion überschreiben, die allerdings private ist. Ist das möglich? Weil bis jetzt klappt es nur, wenn ich auch die public Funktion übernehme, in der die private Funktion aufgerufen wird. Aber da in der public Funktion noch einige weitere private Funktionen aufgerufen werden und ich die nicht mit parent::functionName() aufrufen kann, muss ich die auch alle noch in meine Klasse übernehmen. Und so wird dann aus einer Funktion, die ich überschreiben wollte, ganz viele Funktionen, die ich dann letztendlich in meiner Klasse habe. Ist das irgendwie anders möglich, sodass ich möglichst nur die eine überschriebene private Funktion in meiner Klasse habe?

Danke schon mal im Voraus!

EDIT:

Ich weiche übrigens leicht von der Anleitung ab, da es für den Service kein Interface gibt. Anstatt “implements …Interface” mache ich also “extends …” und dann rufe ich in meinem Konstruktor, der genau die gleichen Parameter hat wie der Service, den parent Konstruktor mit den Parametern auf.

@iNono schrieb:

EDIT:

Ich weiche übrigens leicht von der Anleitung ab, da es für den Service kein Interface gibt. Anstatt „implements …Interface“ mache ich also „extends …“ und dann rufe ich in meinem Konstruktor, der genau die gleichen Parameter hat wie der Service, den parent Konstruktor mit den Parametern auf.

Das ist eine ganz schlecht Idee, da es einen wichtigen Vorteil vom Decorate Pattern zunichtemacht. Stelle dir vor es gibt den Core-Service, dieser wird von Plugin 1 dekoriert. Nun kommt dein Plugin und dekoriert ihn ebenfalls. Wenn du nun von der Core-Klasse erbst, rufst du u.U. nicht mehr den Parent auf (in diesem Beispiel den Service von Plugin 1) sondern die Funktion in der Core-Klasse (nicht Instanz!) und den Plugin ist inkompatibel zu Plugin 1.

Ansonsten: Nein, du kannst keine private-Methoden überschreiben, da diese nicht in deinem Scope liegen. Best Practice: Hole dir das Ergebnis vom Parent-Service und modifiziere es. 

Viele Grüße

Welchen Service möchtest Du den dekorieren? 

@Thomas schrieb:

Welchen Service möchtest Du den dekorieren? 

Den Compiler, also shopware\engine\Shopware\Components\Theme\Compiler.php. Und dort die Funktion compileLessDefinition, um direkt am Anfang zu returnen, falls die Definition ein bestimmtes Kriterium erfüllt. Und somit muss ich die Funktion compileLess und alle privaten Funktionen, die darin benutzt werden, auch übernehmen. Und das Best Practice von @simkli geht somit auch nicht, da die compileLess direkt in die Datei schreibt und nicht erst ein Ergebnis zurück gibt, welches ich bearbeiten kann, wenn ich erst die parent Funktion aufrufen würde.

 

@simkli schrieb:

Das ist eine ganz schlecht Idee, da es einen wichtigen Vorteil vom Decorate Pattern zunichtemacht.

Verstehe ich nicht ganz. Was davon ist nicht richtig? Das extend allgemein oder das mit dem parent Konstruktor? Wie wäre es denn richtig, wenn es kein Interface gibt, so wie in dem Beispiel aus der Anleitung?