Hallo,
ich beschäftige mich im Moment aus Interesse mit dem Observer-Pattern und habe dazu mehrere Fragen, die alle jedoch eher theoretischer Natur sind, sich also nicht auf schon vorhandene Implementationen beziehen.
Allgemein sieht das Entwurfsmuster implementiert ja in etwa so aus:
Was spricht aber dagegen, Observeable und ObserveableClass so zu implementieren:
Hieran finde ich persönlich schöner, dass ich nicht immer in der ObserveableClass jede der Methoden einzeln implementieren muss, zumal das Hinzufügen, Entfernen oder Informieren eines Observers (fast) immer gleich abläuft und man notfalls eine abweichende Methode die bestehende überschreiben kann.
Was mich aber immer noch stört, ist, dass wenn ich das Objekt erzeugt habe, zuerst immer noch die Observers hinzufügen muss, bevor ich mit dem Objekt arbeiten kann. Normalerweise sollte es ja im Programmablauf so sein, dass wenn beim Benutzer A ein ObserveableClass-Objekt instanziiert wird, beim Benutzer B das gleiche Objekt erzeugt wird - zumindest gleich bezogen auf die ObservingClasses. Dann ließe sich das Hinzufügen der Observers ja eigentlich auch in den Konstruktor verbannen:
Somit hätte ich nach dem Instanziieren ein "fertiges" Objekt, mit dem ich weiterarbeiten kann.
Abschließend habe ich noch eine weitere Frage:
Ich habe einen fertigen Programmablauf, den ich jedoch mit einem PlugIn erweitern möchte. Dieses PlugIn soll im Grunde nichts Spektakuläres machen - beispielsweise wenn bei obigem Beispiel die doSomething()-Methode aufgerufen wird, das aktuelle Objekt serialisieren und irgendwo speichern, also irgendwie so:
Wie bekomme ich jetzt aber diesen Observer in mein fertiges Programm, ohne dieses zu verändern? Hierfür müsste ich ja den Observer meiner ObserveableClass bzw. meinen ObserveableClass-Objekt bekannt machen, was aber ohne Veränderung des bereits bestehenden Programmcodes nicht möglich ist - und dafür sind die Observers ja gerade da, dass man den Programmcode nicht verändern muss.
Könnte mir hier jemand weiterhelfen?
ich beschäftige mich im Moment aus Interesse mit dem Observer-Pattern und habe dazu mehrere Fragen, die alle jedoch eher theoretischer Natur sind, sich also nicht auf schon vorhandene Implementationen beziehen.
Allgemein sieht das Entwurfsmuster implementiert ja in etwa so aus:
PHP-Code:
<?php
interface Observer {
public function update(Observeable $victim);
}
interface Observeable {
public function add(Observer $observer);
public function remove(Observer $observer);
public function notify();
}
class ObserveableClass implements Observeable {
protected $observers = Array();
public function add(Observer $observer) {
$this->observers[] = $observer;
}
public function remove(Observer $observer) {
$offset = array_search($observer, $this->observers);
if($offset !== false) unset($this->observers[$offset]);
}
public function notify() {
foreach($this->observers as $observer) $observer->update($this);
}
public function doSomething() {
$this->notify();
}
}
class ObservingClass implements Observer {
public function update(Observeable $observedClass) {
echo "I'm observing you!";
}
}
class ObservingClass2 implements Observer {
public function update(Observeable $observedClass) {
echo "I'm observing you, too!";
}
}
$observeableClass = new ObserveableClass();
$bigBrother = new ObservingClass();
$bigBrother2 = new ObservingClass2();
$observeableClass->add($bigBrother);
$observeableClass->doSomething();
// as exected: echos "I'm observing you!"
$observeableClass->remove($bigBrother);
$observeableClass->add($bigBrother2);
$observeableClass->doSomething();
// as exected: echos "I'm observing you, too!"
?>
PHP-Code:
<?php
// ...
abstract class Observeable {
protected $observers = Array();
public function add(Observer $observer) {
$this->observers[] = $observer;
}
public function remove(Observer $observer) {
$offset = array_search($observer, $this->observers);
if($offset !== false) unset($this->observers[$offset]);
}
public function notify() {
foreach($this->observers as $observer) $observer->update($this);
}
}
class ObserveableClass extends Observeable {
public function doSomething() {
$this->notify();
}
}
// ...
?>
Was mich aber immer noch stört, ist, dass wenn ich das Objekt erzeugt habe, zuerst immer noch die Observers hinzufügen muss, bevor ich mit dem Objekt arbeiten kann. Normalerweise sollte es ja im Programmablauf so sein, dass wenn beim Benutzer A ein ObserveableClass-Objekt instanziiert wird, beim Benutzer B das gleiche Objekt erzeugt wird - zumindest gleich bezogen auf die ObservingClasses. Dann ließe sich das Hinzufügen der Observers ja eigentlich auch in den Konstruktor verbannen:
PHP-Code:
<?php
interface Observer {
public function update(Observeable $victim);
}
interface Observeable {
public function add(Observer $observer);
public function remove(Observer $observer);
public function notify();
}
class ObserveableClass implements Observeable {
protected $observers = Array();
public function __construct() {
$bigBrother = new ObservingClass();
$this->add($bigBrother);
$this->doSomething();
}
public function add(Observer $observer) {
$this->observers[] = $observer;
}
public function remove(Observer $observer) {
$offset = array_search($observer, $this->observers);
if($offset !== false) unset($this->observers[$offset]);
}
public function notify() {
foreach($this->observers as $observer) $observer->update($this);
}
public function doSomething() {
$this->notify();
}
}
class ObservingClass implements Observer {
public function update(Observeable $observedClass) {
echo "I'm observing you!";
}
}
$observeableClass = new ObserveableClass();
// as exected: echos "I'm observing you!"
?>
Abschließend habe ich noch eine weitere Frage:
Ich habe einen fertigen Programmablauf, den ich jedoch mit einem PlugIn erweitern möchte. Dieses PlugIn soll im Grunde nichts Spektakuläres machen - beispielsweise wenn bei obigem Beispiel die doSomething()-Methode aufgerufen wird, das aktuelle Objekt serialisieren und irgendwo speichern, also irgendwie so:
PHP-Code:
<?php
// ...
class ObservingClassS implements Observer {
public function update(Observeable $observedClass) {
$serialized = serizalize($observedClass);
// save
}
}
// ...
?>
Könnte mir hier jemand weiterhelfen?
Kommentar