Sie sind nicht angemeldet.

dfex

Junior Schreiberling

  • »dfex« ist männlich
  • »dfex« ist der Autor dieses Themas

Beiträge: 248

Registrierungsdatum: 11.12.2001

1

26.07.2006, 14:19

Java: kann Superklasse Felder bzw. Methodenaufrufe einer Subklasse überwachen?

Hallo ..

Ich möchte von einer Superklasse aus, beliebige Felder von beliebigen Subklassen überwachen um Änderungen an diesen feststellen zu können (Oder auch den Aufruf von Methoden in der Subklasse überwachen).

Gibt es dazu ausser AspectJ /\ noch Möglichkeiten?
(edit: und AspectJ ähnlichen Compilern)

Falls nicht, wäre ich auch sehr dankbar über Ideen, die mögliche andere Wege oder Workarounds darstellen, wie eine Superklasse Änderungen an ihren Subklassen mitbekommt, (am besten) ohne zusätzlichen Code in den Subklassen.

Danke.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »dfex« (26.07.2006, 14:32)


kakTuZ

größtenteils harmlos

  • »kakTuZ« ist männlich

Beiträge: 309

Registrierungsdatum: 14.10.2003

Wohnort: Hannover

Beruf: Software Developer

2

27.07.2006, 13:40

RE: Java: kann Superklasse Felder bzw. Methodenaufrufe einer Subklasse überwachen?

Zitat

Original von dfex
...wie eine Superklasse Änderungen an ihren Subklassen mitbekommt.

Das ist etwas ungünstig formuliert glaub ich, deswegen kann ich es auch falsch verstanden haben.
Ne einfache Sache mit zusätzlichem code wäre einfach in den Methoden der Subklassen, die den Zustand ändern am ende die Methode in der Superklasse aufrufen, die auf die veränderung reagieren soll.
#! /bin/bash
yes 'arch is still the best'

dfex

Junior Schreiberling

  • »dfex« ist männlich
  • »dfex« ist der Autor dieses Themas

Beiträge: 248

Registrierungsdatum: 11.12.2001

3

27.07.2006, 14:37

RE: Java: kann Superklasse Felder bzw. Methodenaufrufe einer Subklasse überwachen?

ja, genau das ist der einfachste Anstatz, den ich auch schon in betracht gezogen habe. Leider gibt mir das noch keine Sicherheit, ob wirklich alle implementierten Subklassen diesen "Notifier" der Superklasse aufrufen.
Die Frage ist halt: Was ist, wenn ein Entwickler das vergisst?

Man könnte natürlich sagen, Pech gehabt. Allerdings suchte ich ja gerade (freundlicherweise) eine Lösung, bei der das Ganze ohne zusätzlichen Code in den Subklassen funktioniert, sodass ein Vergessen seitens eines Programmieres nicht passieren kann.

kakTuZ

größtenteils harmlos

  • »kakTuZ« ist männlich

Beiträge: 309

Registrierungsdatum: 14.10.2003

Wohnort: Hannover

Beruf: Software Developer

4

27.07.2006, 16:30

Eine andere recht einfache möglichkeit wär wohl, die Funktionsaufrufe der Subklassen zu kapseln. Funktioniert aber nur, wenn das ganze Polymorph verwendet wird.

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Super
{
    ...
    public void fn()
    {
         fn_implementierung();
         reagiereAufÄnderungen();
    }
    protectd void fn_implementierung() {nix}
}
class Sub : extends Super
{
    protectd void fn_implementierung() {doSomething();}
}


Oder was ganz anderes. Vielleicht kann man mit dem Reflection Krams was machen.
#! /bin/bash
yes 'arch is still the best'

DrChaotica

Senior Schreiberling

  • »DrChaotica« ist männlich

Beiträge: 714

Registrierungsdatum: 22.01.2005

Wohnort: SHG

Beruf: SW-Entwickler

5

27.07.2006, 18:29

Deine Funktionen bräuchten so eine Art Interface, das sicherstellt, dass sie Änderungen an die Superklasse melden bzw. dass dort automatisch ein Check durchgeführt wird... da es sowas für Funktionen ja nicht gibt, wie wäre es denn, wenn Du um jede Methode der Superklasse in ein Objekt wrappen würdest, das ein solches Interface implementieren muss?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »DrChaotica« (27.07.2006, 18:31)


silence

Junior Schreiberling

Beiträge: 177

Registrierungsdatum: 11.12.2001

Wohnort: reagenzglas

Beruf: tellerwäscher

6

27.07.2006, 20:45

Am einfachsten geht das Ganze mit AOP, also z. B. AspectJ. Einfach einen Pointcut definieren, der bei allen Schreibzugriffen in den Feldern der Subklassen greift. Mit einem passenden Advise kann man dann lustige Aktionen starten. Doch obacht: Mit sowas schiesst man sich gaaanz schnell in den eigenen Fuß ;)
"Wir stecken immer in der Scheisse, nur die Tiefe ändert sich."
(Ein unbekannter Softwareentwickler)

Hogi

Trainee

  • »Hogi« ist männlich

Beiträge: 69

Registrierungsdatum: 08.10.2003

Wohnort: Rinteln

7

27.07.2006, 22:50

und das ausgerechnet mit java... wo metaprogramming doch nun wirklich nicht dessen stärke ist. mit ruby oder ähnlichem sollte das kein problem darstellen..

naja, also zu meinen ideen:

spontan ist mir eingefallen, dass beim Aufruf von konstruktoren in der subklasse automatisch zuerst der default-konstruktor der superklasse aufgerufen wird, dies kann also kein entwickler vergessen... möglicherweise kannst du dann ausnutzen, dass du beim aufruf von getClass() im default-konstruktor der superklasse netterweise die subklasse bekommst. da kannst du dann mit den ganzen reflections-sachen herausfinden welche felder und methoden es gibt, und diese dann auch in begrenztem umfange manipulieren.

ich warne dich aber gleich: beim drauflosprogrammieren habe ich dort noch keine möglichkeit gefunden, mich da irgendwie einzuhaken oder die methoden gar zu verändern... leider...

so bleibt dir wohl erstmal nur die möglichkeit, wenn du nach wie vor auf aop verzichten willst, eine art code-generator zu schreiben, der jede klasse vor dem build durchpflügt und dort in jede methode den hook einbaut...

sowohl mit ruby als auch mit aspectj ist das so unendlich viel einfacher, aber vermutlich hast du vorgaben, die dir das verbieten...

Hogi

Trainee

  • »Hogi« ist männlich

Beiträge: 69

Registrierungsdatum: 08.10.2003

Wohnort: Rinteln

8

28.07.2006, 13:05

hey.. mir kam gerade noch eine idee, mit der du zumindest sicherstellen kannst, dass es kein entwickler vergisst, auch wenn du dadurch code in der subklasse hast:

der default-konstruktor der superklasse durchläuft mit getClass().getDeclaredMethods() alle methoden, auch die der subklasse, und überprüft, ob bei deren aufruf der notifier korrekt aufgerufen wird. ist dies nicht der fall, dann wirfst du eine RuntimeException, die den entwickler dann auf das problem hinweist.. zur not (also wenn du dir nicht dein schönes objekt versauen willst) kannst du mit getClass().newInstance() auch eine jungfräuliche instanz erstellen)...

ein anderer weg könnte sein, mit JUnitTest einfach einen testfall für jede methode und jede variable zu erstellen (natürlich wieder mit reflections automatisiert) und sicherzustellen, dass jeder aufruf und jede variablenänderung registriert wird... dazu müssten die nutzer deiner superlasse natürlich irgendwie im selben projekt arbeiten und es muss die policy geben, unit-tests auch zu benutzen.. dürfte klar sein...

dfex

Junior Schreiberling

  • »dfex« ist männlich
  • »dfex« ist der Autor dieses Themas

Beiträge: 248

Registrierungsdatum: 11.12.2001

9

29.07.2006, 15:10

Zitat

Original von kakTuZ
Eine andere recht einfache möglichkeit wär wohl, die Funktionsaufrufe der Subklassen zu kapseln. Funktioniert aber nur, wenn das ganze Polymorph verwendet wird.

Ja, das funktioniert allerdings nur, wenn die Methoden bekannt sind. In meinem Falle sind sie das leider nicht.


Zitat

Original von Hogi
... mit aspectj ist das so unendlich viel einfacher ...

ich gebe dir sowas von recht :)


Zitat

Original von Hogi
der default-konstruktor der superklasse durchläuft mit getClass().getDeclaredMethods() alle methoden, auch die der subklasse, und überprüft, ob bei deren aufruf der notifier korrekt aufgerufen wird.

hmm, das hört sich nach einem netten Ansatz an. Wie stelle ich denn sicher, dass der Notifier dann auch in den Methoden steckt, wenn ich sie als MethodenObjekte vorliegen habe? Da stehe ich wohl gerade auf dem Schlauch ...

Zitat

Original von Hogi
ein anderer weg könnte sein, mit JUnitTest einfach einen testfall für jede methode und jede variable zu erstellen ...

HA! Das werde ich auf jedenfall unabhängig von allem anderen noch machen.

Danke.

Hogi

Trainee

  • »Hogi« ist männlich

Beiträge: 69

Registrierungsdatum: 08.10.2003

Wohnort: Rinteln

10

29.07.2006, 15:51

Zitat

Original von dfex

Zitat

Original von Hogi
der default-konstruktor der superklasse durchläuft mit getClass().getDeclaredMethods() alle methoden, auch die der subklasse, und überprüft, ob bei deren aufruf der notifier korrekt aufgerufen wird.

hmm, das hört sich nach einem netten Ansatz an. Wie stelle ich denn sicher, dass der Notifier dann auch in den Methoden steckt, wenn ich sie als MethodenObjekte vorliegen habe? Da stehe ich wohl gerade auf dem Schlauch


na ja, du könntest ja deinen notifier-test-code einfach genauso bei dem zu überprüfenden objekt registrieren, wie du das später im einsatz auch tun würdest (ich gehe mal vom observer-pattern aus, also dass alle objekte irgendwie observable sind, und dein analyse-code der observer). dann könntest du nach und nach jede methode mit invoke() aufrufen und und schauen, ob der notifier etwas gemerkt hat (der müsste dann ja in allen observern eine bestimmte methode aufrufen, notify() oder so ähnlich), wenn er was gemerkt hat (also wenn diese methode aufgerufen wurde) ist alles in butter, ansonsten musst du die exception schmeissen...