![]() |
Abhängigkeit von Klassen unmöglich?
Hallo,
der folgende Code ist in PHP-Syntax, es handelt sich jedoch um eine allgemeine Aufgabenstellung. Ich habe eine Klasse "Cache". Im Konstruktor kann ich den Cache aktivieren oder deaktivieren:
Code:
Diesen boolschen Wert würde ich gerne aus einer Konfigurationstabelle in der Datenbank auslesen. Die Schwierigkeit ist jedoch, dass ich die Konfigurationsdaten cache, da sich diese nur selten ändern:
$cache = new cache(true); // aktiviert
$cache = new cache(false); // deaktiviert
Code:
Das heißt, für die Konfigurationsdaten muss eine Instanz der Cache-Klasse existieren. Allerdings brauche ich zum Erstellen der Instanz wiederum die Konfigurationswerte.
$config_data = $cache->get_data('config');
Wie löst man das? :gruebel: Grüße, Matze |
Re: Abhängigkeit von Klassen unmöglich?
Ist die Cache-Konfiguration tatsächluch Instanz-spezifisch? Wenn nicht, dann ist das ganz einfach über statische Methoden / Felder lösbar...
![]() Allerdings teilen dann natürlich alle Instanzen von Cache die selbe Konfiguration. Aber ich schätze mal mehr als einen cache gibt es sowieso nicht? |
Re: Abhängigkeit von Klassen unmöglich?
Richtig, es gibt nur eine Instanz, aber ich wüsste nicht, in wie weit mir das helfen soll.
So oder so muss ich dem Cache den Wert aus der (ggf. gecachten) Konfiguration vorgeben. |
Re: Abhängigkeit von Klassen unmöglich?
Du kannst jederzeit nach dem Erstellen der Klasse und dem Bemerken der Tatsache dass Du den anderen Konstruktor gebraucht hättest, die neue Klasse ein zweites mal richtig erzeugen und die Werte rüberkopieren und dann den Instanzverweis umbiegen.
|
Re: Abhängigkeit von Klassen unmöglich?
Ich glaube, was ich gerne hätte, geht einfach nicht.
Es würde gehen, wenn ich sage, dass die Konfigurationsdaten immer oder nie aus dem Cache kommen. Dann könnte ich danach auch den Konstruktor neu aufrufen mit dem entsprechenden Wert. Ich hätte es gerne so: Wert aus der Konfiguration lesen => wenn dort Cache deaktiviert, Konfiguration aus der Datenbank holen, sonst aus dem Cache |
Re: Abhängigkeit von Klassen unmöglich?
Cache ist doch eine selbst erstellte Klasse. Warum kann diese Klasse sich den Wert zum cachen nicht selbst besorgen? Das würde sie zwar dann jedes mal machen, aber das wird wohl nicht das Problem sein.
Zitat:
Bernhard |
Re: Abhängigkeit von Klassen unmöglich?
Zitat:
|
Re: Abhängigkeit von Klassen unmöglich?
Zitat:
Sonst kann ich die gleich aus der Datenbank auslesen (immer), wenn ich zum Auslesen eine Verbindung brauche. |
Re: Abhängigkeit von Klassen unmöglich?
Vielleicht fehlt mir grad ein wenig Hintergrundwissen zu PHP, aber ich dachte, wenn ein PHP-Request durch ist, dann wird der Handler aus Performancegründen entladen und damit sowieso alle Klassen aufgeräumt?
Sowas wir einen Workerprozess der permanent solche Singleton-Instanzen im Speicher hält gibt es doch da gar nicht, oder etwa doch? |
Re: Abhängigkeit von Klassen unmöglich?
Nicht, dass ich wüsste. Aber davon habe ich doch auch gar nichts geschrieben. :gruebel:
|
Re: Abhängigkeit von Klassen unmöglich?
Ich dachte es gibt für PHP 2 Methoden, wie dieses Modul aufgerufen wird?
- sowas wie 'ne DLL, welche bei jedem Request neu geladen wird - und quasi als EXE, welche ständig aktiv ist und z.B. vom "Apache" die Requests zugeschockt bekommt, aber Klassen und der restliche zum Request gehörende Speicher werden wohl so oder so jedesmal neu geladen und am Ende freigegeben. Wenn man diese Klasse aber in der Session serialisiert hat, dann könnte man sie von dort jeweils neu rausladen. |
Re: Abhängigkeit von Klassen unmöglich?
Zitat:
Welchen Sinn macht ein Cache, der über den Konstruktor deaktiviert werden kann? (rhetorische Frage ;-) Man kann den Cache-Size auf 0 setzen, so dass im Prinzip jeder Zugriff auf den Cache zu einen "Miss" wird. Oder es gibt eine Methode ClearCache. Aber ein An/Aus-Flag im Konstruktor is nicht gut. |
Re: Abhängigkeit von Klassen unmöglich?
Ich kenne das Cachen von DB-Abfragen von einer Shopsoftware. Dabei werden die Ergebnisse in eine (bzw in mehreren) Dateien zwischengespeichert.
Zu deinem Parameter-Problem: ich würde das nicht über einen Parameter steuern. Ich würde der Klasse Cache selbst die Entscheidung überlassen, ob eine bestimmte Abfrage gecached werden soll oder nicht. Du kannst dir ja eine Zeitspanne überlegen, nach der die zwischengespeicherten Informationen verfallen. Das kannst du sogar für jede Abfrage getrennt verwalten. |
Re: Abhängigkeit von Klassen unmöglich?
Hallo
Zitat:
So übel finde ich das gar nicht. Zitat:
Notfalls lege ich den Cache-Status über eine Konfigurationsdatei fest. Es wäre halt schön gewesen, das übers Admin-Panel zu erledigen. Grüße, Matze |
Re: Abhängigkeit von Klassen unmöglich?
Moin Matthias,
Zitat:
Über den Konstruktor initial den Cache ein- bzw. auszuschalten kannst Du dann auch zusätzlich machen, wenn Du hierbei Einschalten als Defaultwert annimmst, hast Du wahrscheinlich auch das Problem mit den Configdaten erschlagen. |
Re: Abhängigkeit von Klassen unmöglich?
Hallo Christian
Zitat:
Ich kann mal den genauen Code zeigen, wie ich die Daten zur zeit hole. Nur ob das zu einer Lösungsfundung beiträgt, weiß ich nicht:
Code:
Ich könnte natürlich die ganzen Codestellen so abändern, aber das gefällt mir nicht sonderlich:
$data = $cache->get('somedata.php');
if ($data === false) // Cache abgelaufen oder Cache deaktiviert { $data = ...; // aus der Datenbank holen $cache->put('somedata.php'); }
Code:
Wobei das zur Not sicher ginge.
if ($cache_enabled)
{ $data = $cache->get('somedata.php'); if ($data === false) // Cache abgelaufen oder Cache deaktiviert { $data = ...; // aus der Datenbank holen $cache->put('somedata.php'); } } else { $data = ...; // aus der Datenbank holen } Edit: Wobei ne, da hätte ich das gleiche Problem. Grüße, Matze |
Re: Abhängigkeit von Klassen unmöglich?
also irgendwie würde ich das anders designen. dein code will daten anfordern...
dann geht es ihn doch eigentlich nichts an ob die daten nun aus dem cache kommen oder direkt aus der DB. ich würde noch eine daten-klasse dazwischen klemmen die dann entscheidet ob aus dem cache gelesen wird oder aus der DB.
Code:
und ob forceDB auf true gesetzt wird kannst du dann ja auf verschiedene
class Data
{ private $cache; public $forceDB = false; public function __construct() { $this->cache = new Cache(); } public function get($name) { $data = false; if(!$this->forceDB) $data = $cache->get($name); if($data === false) { //aus DB lesen $data = ...; $cache->set($name, $data); } return $data; } } $data = new Data(); $data->forceDB = true; echo $data->get('blabla'); art und weise implementieren. du könntest das z.B. über einen parameter machen den du deinem script übergibst. oder du stellst das im admin-panel ein und speicherst es in deiner session. wenn ich das richtig verstanden habe soll der cache ja nur für dich zum testen deaktiviert werden, oder? dann wär das ja vollkommen ausreichend. |
Re: Abhängigkeit von Klassen unmöglich?
Ich denke dass "nat" auf der richtigen Spur ist.
Eigentlich benötigt man eine Proxy-Klasse, die einen Cache benützt. Und es gibt noch ein Dateninterface; also die Schnittstelle über die Daten geholt werden. Ein ganz einfaches Interface sieht so z.B. so aus:
Delphi-Quellcode:
Das heisst jetzt nicht, dass man wirklich Interfaces verwenden muss; es dient nur zur gedanklichen Vorstellung.
IDataInterface = interface
// liefert einen Wert anhand eines Schlüssel function GetData(key:string):string; end; Dann sähe das "Objektschaltbild" so aus:
Code:
Jetzt schalten wir ein Proxyobjekt zwischen den Konsument und das Datenobjekt.
Konsument <-- Datenobjekt
Das Proxyobjekt hat die gleiche Schnittstelle wie das Datenobjekt. Sowohl das Proxyobjekt als auch das Datenobjekt implementieren die gleiche Schnittstelle. Der Konsument merkt also gar nicht, ob es direkt auf dem Datenobjekt arbeitet oder mit dem Proxy redet:
Code:
Die Proxyklasse erhält im Konstruktor das Datenobjekt übergeben.
Konsument <-- Proxy <-- Datenobjekt
| | Cache Der Datenfluss durch den Proxy geht im Bild oben nur in eine Richtung. Man kann den Proxy aber auch so bauen, dass auch Daten vom Konsument zum Datenobjekt fliesen.
Code:
Hierbei gibt es mindestens drei Varianten:
Konsument/Produzent <--> Proxy <--> Datenobjekt
| | Cache 1.) Der Proxy schiebt die Daten nur in den Cache und markiert sie (dirty bit) als verändert. Später werden alle veränderten Daten zum Datenobjekt zurückgeschrieben 2.) Der Proxy schreibt direkt durch zum Datenobjekt (write-through) 3.) Der Proxy schreibt direkt durch zum Datenobjekt und zusätzlich in den Cache Man braucht so mehr Klassen, aber dürfte so kein Problem sein, den Proxy zur Laufzeit in den Transparentmode zu versetzen. Vielleicht arbeitet auch irgend jemand am Proxy vorbei und es könnte nötig werden den Cache zu löschen, weil die Daten nicht mehr aktuell sind. |
Re: Abhängigkeit von Klassen unmöglich?
Moin,
@nat: implementier doch auch gleich Dependency Injection:
Code:
Der Vorteil ist, dass du dann Cache auch als Singleton implementieren kannst:
class Data
{ private $cache; public $forceDB = false; public function __construct($cache) { $this->cache = $cache; } public function get($name) { $data = false; if(!$this->forceDB && $this->cache) $data = $this->cache->get($name); if($data === false) { //aus DB lesen $data = ...; if ($this->cache) $this->cache->set($name, $data); } return $data; } } $data = new Data(new Cache()); $data->forceDB = true; echo $data->get('blabla');
Code:
Greetz
$data = new Data(Cache::getInstance());
alcaeus |
Re: Abhängigkeit von Klassen unmöglich?
Zitat:
mag ich es jedoch auch, wenn die klasse sich selber darum kümmert was sie benötigt. wird das ganze allerdings komplexer ist es schon von vorteil, wenn die klasse nicht von etlichen anderen abhängig ist. Zitat:
um den kompletten page-content auszugeben, von daher ist das denke ich mal nicht zwingend nötig. wenn man jedoch nur einzelne elemente quer über den source hinweg cached (z.B. alle DB-queries) macht es sicher sinn. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:54 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz