In allen obigen Beispielen ist das Erzeugen des
Thread-Objekts
sehr ähnlich. Das Stück Programmcode unterscheidet sich nur an einer einzigen
Stelle: Was passiert nach dem Ablauf der Schlafperiode (1 oder 3 Sekunden). Bei
den monolithischen Programmen wird die Methode
this.tick()
aufgerufen, in der MVC-Version
model.tick() und
view.tick(),
in der Observer-Version
notifyObservers("Tick") oder
notifyObservers(Ereignis.TICK). Es liegt an
der Hand, den Code aus dem Konstruktor in eine Methode auszulagern; aber die
Übergabe einer Anweisungsfolge oder einer aufzurufenden Methode als Parameter
ist in Java nicht vorgesehen. (In anderen Sprachen wie C oder C# ist dies
möglich).
In Java kann eine Methode als Parameter nicht übergeben
werden, wohl aber ein Objekt, dessen Klasse diese Methode enthält. In
verschiedenen Situationen werden verschiedene Objekte übergeben, deren Klassen
eine gemeinsame Schnittstelle implementieren.
Dieses Muster können wir folgendermaßen implementieren:
public interface Delegat {
// gemeinsame Schnittstelle
void aktion();
// (formale) Delegatmethode
long
getFrequenz(); }
public
class
Ticken {
public
static
void
ticken(final
Delegat d) {
// gemeinsamer
Codeteil
new
Thread() {
@Override
public
void
run() {
try
{
while
(true) {
Thread.sleep(d.getFrequenz());
d.aktion(); // unterschiedlicher
Codeteil
} }
catch (InterruptedException e) { } }
}.start(); } }
Der Aufruf der Methode
ticken() aus
DigitalUhr und aus
KreisUhr
erfolgt im Konstruktor:
DigitalUhr() {
… // Oberfläche aufbauen wie
oben
pack();
setVisible(true);
Ticken.ticken(new
Delegat() { // Aufruf der Methode mit
Delegatparameter
@Override
public
void aktion() { // aktuelle
Delegatmethode
tick(); }
public long getFrequenz() {
return
frequenz;
} }); }
Der Konstruktor der abstrakten Klasse
Control aus der Lösung MVC mit
Observer ist wie folgt:
Control(final IModel model) {
Ticken.ticken(new
Delegat() { // Aufruf der Methode mit
Delegatparameter
@Override
public
void aktion() { // aktuelle
Delegatmethode
setChanged();
notifyObservers("Tick");
}
public long getFrequenz() {
return
model.getFrequenz(); } }); }
während die Lösung mit generischem Observer unterscheidet
sich ähnlich auch nur im Rumpf der Delegatmethode
aktion():
public
void
aktion() {
notifyObservers(Ereignis.TICK); }
Mit Hilfe eines Delegats ist es also möglich, gemeinsame
Codeteile in eine Methode auszulagern, selbst wenn sie dabei unterschiedliche
Codeteile enthalten. Gegebenenfalls kann die Delegatmethode auch parametrisiert
werden.
Version: 22. April 2012
© Prof. Solymosi, 20102 Beuth-Hochschule für Technik Berlin, Fachbereich VI (Informatik und Medien)
solymosibht-berlin.de