Dies ist eine statische Kopie unseres alten Forums. Es sind keine Interaktionen möglich.
This is a static copy of our old forum. Interactions are not possible.

dfex

Junior Schreiberling

  • "dfex" is male
  • "dfex" started this thread

Posts: 248

Date of registration: Dec 11th 2001

1

Wednesday, July 26th 2006, 2:19pm

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.

This post has been edited 2 times, last edit by "dfex" (Jul 26th 2006, 2:32pm)


kakTuZ

größtenteils harmlos

  • "kakTuZ" is male

Posts: 309

Date of registration: Oct 14th 2003

Location: Hannover

Occupation: Software Developer

2

Thursday, July 27th 2006, 1:40pm

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

Quoted

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" is male
  • "dfex" started this thread

Posts: 248

Date of registration: Dec 11th 2001

3

Thursday, July 27th 2006, 2:37pm

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" is male

Posts: 309

Date of registration: Oct 14th 2003

Location: Hannover

Occupation: Software Developer

4

Thursday, July 27th 2006, 4:30pm

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

Source code

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" is male

Posts: 714

Date of registration: Jan 22nd 2005

Location: SHG

Occupation: SW-Entwickler

5

Thursday, July 27th 2006, 6:29pm

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?

This post has been edited 1 times, last edit by "DrChaotica" (Jul 27th 2006, 6:31pm)


silence

Junior Schreiberling

Posts: 177

Date of registration: Dec 11th 2001

Location: reagenzglas

Occupation: tellerwäscher

6

Thursday, July 27th 2006, 8:45pm

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" is male

Posts: 69

Date of registration: Oct 8th 2003

Location: Rinteln

7

Thursday, July 27th 2006, 10:50pm

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" is male

Posts: 69

Date of registration: Oct 8th 2003

Location: Rinteln

8

Friday, July 28th 2006, 1:05pm

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" is male
  • "dfex" started this thread

Posts: 248

Date of registration: Dec 11th 2001

9

Saturday, July 29th 2006, 3:10pm

Quoted

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.


Quoted

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

ich gebe dir sowas von recht :)


Quoted

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 ...

Quoted

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" is male

Posts: 69

Date of registration: Oct 8th 2003

Location: Rinteln

10

Saturday, July 29th 2006, 3:51pm

Quoted

Original von dfex

Quoted

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...