Hallo,
Ich möchte optional Daten, die in den Methoden {before,after}Persists gewonnen werden an den aufrufenden Code übergeben. Beide Methoden führen übergebene callables aus. (Callbacks sind an eine Instanz einer abgeleiteten Repository Klasse gebunden z.B. UserRepository).
Meine erste Idee war es den Rückgabewert abhängig vom Vorhandensein des SplObjectStorage-Objekts(oder gegen was auch immer ich dies später austauschen sollte) zu machen und in diesem Falle das Objekt anstelle von true/false zurückzugeben. Allerdings ist das wohl nicht die praktikabelste Möglichkeit, da a) Mir beim Aufruf der Methode nicht bekannt ist, ob überhaupt zusätzlicher Code ausgeführt wird und b) auch Daten im Objekt abgelegt werden könnten, wenn die eigentliche Aktion fehlschlägt. Desweiteren soll das ganze wie gesagt optional sein.
Unten steht meine aktuelle Idee, bei der ich mir jedoch ebensowenig sicher bin, ob dies der richtige Weg ist.
Zumeinen erzeuge ich in vielen Fällen ein Objekt, welches nie wirklich verwand wird, zum anderen kommen mir Zweifel auf, ob ich hier nicht die eigentliche Logik eines Repositories überschreite und der Teil nicht in einen komplett anderen Part der Anwendung wandern sollte und ob es, wenn dies nicht der Fall ist, eine bessere Möglichkeit der Implementierung gibt.
Aus der Luft gerissenes Beispiel eines callbacks
Teilweise Pseudocode und zusammenkopiert(Aus bisheriger Implementierung und abs. Klasse), damit das hier etwas Sinn ergibt:
Ich möchte optional Daten, die in den Methoden {before,after}Persists gewonnen werden an den aufrufenden Code übergeben. Beide Methoden führen übergebene callables aus. (Callbacks sind an eine Instanz einer abgeleiteten Repository Klasse gebunden z.B. UserRepository).
Meine erste Idee war es den Rückgabewert abhängig vom Vorhandensein des SplObjectStorage-Objekts(oder gegen was auch immer ich dies später austauschen sollte) zu machen und in diesem Falle das Objekt anstelle von true/false zurückzugeben. Allerdings ist das wohl nicht die praktikabelste Möglichkeit, da a) Mir beim Aufruf der Methode nicht bekannt ist, ob überhaupt zusätzlicher Code ausgeführt wird und b) auch Daten im Objekt abgelegt werden könnten, wenn die eigentliche Aktion fehlschlägt. Desweiteren soll das ganze wie gesagt optional sein.
Unten steht meine aktuelle Idee, bei der ich mir jedoch ebensowenig sicher bin, ob dies der richtige Weg ist.
Zumeinen erzeuge ich in vielen Fällen ein Objekt, welches nie wirklich verwand wird, zum anderen kommen mir Zweifel auf, ob ich hier nicht die eigentliche Logik eines Repositories überschreite und der Teil nicht in einen komplett anderen Part der Anwendung wandern sollte und ob es, wenn dies nicht der Fall ist, eine bessere Möglichkeit der Implementierung gibt.
Aus der Luft gerissenes Beispiel eines callbacks
PHP-Code:
$c = function(User $user, SplObjectStorage $stack, Repository $repo) {
if($user->hasProfile() && $repo->getStorageType() === 'json') {
$stack[$user]['adminLog'][] = 'A user that is to be saved in a json file has a profile');
}
};
$userRepo->attachAfterPersistHandler($c);
PHP-Code:
abstract class Repository {
public abstract function fetch($id);
public /* abstract */ function persist(IPersistable $obj, SplObjectStorage $msgStack = null) /* ; */
/**/{
if($msgStack === null) {
$msgStack = new \SplObjectStorage;
}
if ($this->beforePersist($obj, $msgStack)) {
if ($this->getStorageAdapter()->save($obj->toPersistableArray())) {
return $this->afterPersist($obj, $msgStack);
} else {
throw new \RuntimeException($this->getStorageAdapter()->getLastErrorMessage());
}
}
return false;
}/**/
public function persistAll(array $objs, \SplObjectStorage $msgStack = null) {
if($msgStack === null) {
$msgStack = new \SplObjectStorage();
}
$ret = [];
/** @var IPersistable $obj */
foreach($objs as $position => $obj) {
if($obj instanceof IPersistable) {
$ret[$position] = $this->persist($obj, $msgStack);
} else {
// handle and throw away
}
}
return $ret;
}
}
Kommentar