# Framework Designfrage



## onemice (19. Okt 2009)

Guten Morgen =)

ich beschäftige mich zur Zeit intensiv mit Java und zum Lernen, dachte ich, implementiere ich mal ein simples MVC Web Framework.

Ich arbeite mit Eclipse und habe nun 2 Projekte: Das Framework selbst und ein Test-Projekt um das Framework testen zu können.

Über die Java EE Module Dependencies des Test-Projekts habe ich das Framework dort referenziert.

Mein Ziel bei dem Framework ist es, dass das Framework die ganze Arbeit übernimmt und der "End-Entwickler" nur noch die Controller, Models, Views und Helper oder sowas implementieren muss.

Bei jedem Aufruf wird die Dispatcher Klasse (implementiert Servlet) des Frameworks ausgeführt ist. Diese ermittelt, anhand der URL (z.B. http://example.com/controller/action) welcher controller und welche Methode des Controllers aufzurufen ist und tut dies entsprechend auch sofern Controller-Klasse und die Action-Methode vorhanden sind.

Mein Problem ist nun: In dem Test-Projekt sind die Klassen des Frameworks sichtbar. Logisch.
In meinem Framework sind die Klassen des Test-Projekts natürlich nicht sichtbar.

Frage: Wie kann ich in meinem Framework eine Klasse des Test-Projekts instanzieren und eine Methode aufrufen?


Vielen Dank im Voraus für die Hilfe


----------



## maki (19. Okt 2009)

Persönlich bin ich zwar der Meinung, dass es dir viel mehr bringen würde dich mit den Grundlagen Servlets & dann mit bestehenden Frameworks wie Struts, JSF, Wicket, Tapestry etc. auseinander zu setzen mehr bringt, aber das ist deine Entscheidung 

Auf keinen Fall solltest du zirkuläre Abhängigkeiten einführen, Eclipse kann die zwar verwalten, aber die daraus resultierende "Struktur" ist Haarsträubend und nicht mit autom. Buildsystemen Kompatibel.

Was und wie  genau willst du denn testen?
Javaklassen deines Frameworks? Die Views (JSPs, etc.)?
Willst du isolierte Komponenten Testen, oder das ganze System?


----------



## onemice (19. Okt 2009)

> Persönlich bin ich zwar der Meinung, dass es dir viel mehr bringen würde dich mit den Grundlagen Servlets & dann mit bestehenden Frameworks wie Struts, JSF, Wicket, Tapestry etc. auseinander zu setzen mehr bringt, aber das ist deine Entscheidung



Jap, halte ich für keine schlechte Idee, wollte mich eben erst mit Java selbst, Design Pattern etc. befassen, mich dann auf jsp & jstl stürzen und dann mal auf die bereits vorhandenen Frameworks.




> Auf keinen Fall solltest du zirkuläre Abhängigkeiten einführen, Eclipse kann die zwar verwalten, aber die daraus resultierende "Struktur" ist Haarsträubend und nicht mit autom. Buildsystemen Kompatibel.



Zirkuläre Abhängigkeiten? Du meinst, die Sache mit den Java EE Module Dependencies? Diese Abhängigkeit hat doch lediglich den selben Effekt, als würde ich mein Framework zu einer Jar-File packen und im Classpath meines Test-Projekts ablegen. Ist so nur eben einfacher.




> Was und wie genau willst du denn testen?
> Javaklassen deines Frameworks? Die Views (JSPs, etc.)?
> Willst du isolierte Komponenten Testen, oder das ganze System?



Ich möchte testen, ob das mit dem Routing klappt. Mehr eigentlich. Das heißt, ich lege in mein Test-Projekt einen Controller, der Hallo Welt ausgibt und das Framework soll diesen Controller instanzieren, die Methode aufrufen und es soll Hallo Welt ausgegeben werden 


Funktioniert ja auch alles prima, nur dass ich nicht genau weiß, wie ich im Framework eine beliebige Klasse des Projekts instanzieren, in dem das Framework verwendet wird, ohne eine Abhänigkeit zu definieren.


----------



## maki (19. Okt 2009)

> Zirkuläre Abhängigkeiten? Du meinst, die Sache mit den Java EE Module Dependencies? Diese Abhängigkeit hat doch lediglich den selben Effekt, als würde ich mein Framework zu einer Jar-File packen und im Classpath meines Test-Projekts ablegen. Ist so nur eben einfacher.


Ich meine dass deine Prod. Klassen deine Testklassen referenzieren und umgekehrt, vermeide das unbedingt.
Selbst wenn beides, Prod & Testklassen im selben Projekt sind, sollten niemals die Testklassen im standard Jar mitausgeliefert werden.

"Klassisch" läuft das so: Die Testklassen referenzieren die Prodklassen, fertig, die Prod Klassen wissen nix von Teestklassen.
Du fragst dich wie du es schaffst deine Tests auszuführen?
Daher kommt meine Frage was und wie du testen möchtest 



> Ich möchte testen, ob das mit dem Routing klappt. Mehr eigentlich. Das heißt, ich lege in mein Test-Projekt einen Controller, der Hallo Welt ausgibt und das Framework soll diesen Controller instanzieren, die Methode aufrufen und es soll Hallo Welt ausgegeben werden


Wo soll Hallo Welt ausgegebn werde? Im browser? Auf der KOnsole? Als rückgabewert einer Methode?

Die frage lautet eigentlich nach Testbaren Klassen und der Möglichkeit, die Abhängigkeit der zu testenden Klasse (hier der Controller) während des testes zu ersetzen. 
Das wiederum bringt uns dann zu Dependency Injection(mit & ohne Framework) und Mock Objekten.
Es gibt zB. mehrere Unittesting Frameworks welche Mocks für HttpServletRequest etc. liefern.

Hört sich alles sehr aufwändig an?
Es wird einfacher wenn man die Logik so gut wie möglich von Dingen wie der Servlet API fernhält, bei einem Controller geht das imho nicht so einfach


----------



## onemice (19. Okt 2009)

> Ich meine dass deine Prod. Klassen deine Testklassen referenzieren und umgekehrt, vermeide das unbedingt.
> Selbst wenn beides, Prod & Testklassen im selben Projekt sind, sollten niemals die Testklassen im standard Jar mitausgeliefert werden.
> 
> "Klassisch" läuft das so: Die Testklassen referenzieren die Prodklassen, fertig, die Prod Klassen wissen nix von Teestklassen.
> ...



Das ist mir klar, dass die Test-Klasen natürlich nichts im Prod. Projekt zu suchen haben. Das ist auch nicht der Fall.

Das Test-Projekt referenziert nur das Framework (sonst kann ich ja nichts testen *g*).

Dir Prod. Klassen dürfen natürlich nichts von den Test-Klassen wissen. Genau das ist ja mein Ziel. Aber ein Framework macht wenig Sinn, wenn es keine Möglichkeit hat die Klassen der App anzusprechen. Denn das Framework soll diese ja Verwalten.




> Wo soll Hallo Welt ausgegebn werde? Im browser? Auf der KOnsole? Als rückgabewert einer Methode?



Mir egal. Ich möchte ja nur sicherstellen, dass das Framework den Controller aufgerufen hat. Hehe


Ich glaube wir reden ein wenig aneinander vorbei. Es geht mir nicht um das Testen des Frameworks es geht mir um die funktionalität des Frameworks.

Ziel des Frameworks soll es sein, dass man die Jar-File in ein Projekt legt und der Code der Jar-File dann die Klassen des Projekts aufruft. Und eben diese Funktionalität würde ich gerne implementieren, weiß nur nicht genau wie :bahnhof:


----------



## mvitz (19. Okt 2009)

So 100% verstanden, was du möchtest habe ich nicht, aber hier zwei Tipps:

1) Mit Interface arbeiten, d.h. alle Controller in der Prod. müssen halt Interface "Controller" implementieren.

2) Damit das Framework die Implementierten Klassen kennt, muss man diese dem Interface bekanntmachen. Z.B. über eine xml, oder property Datei oder direkt über eine Java Datei, in der man im Prod. System nichts anderes macht, als alle benötigten Controller zu instanzieren und diese dem Framework bekannt macht.

P.S.:

Ich habe etwas ähnliches letztes Semester für einen meiner Kurse gemacht, da wir kein bestehendes Framework benutzen sollten. Evtl. ist da ja was für dich dabei:

/trunk - de.hsnr.va.mm - Trac

Das "Framework" selber befindet sich in src/java/de/hsnr/va/mm/mvc das bekanntmachen der Controller in src/java/de/hsnr/va/mm/ui/FrontController

Evtl. hilft das ja.


----------



## onemice (19. Okt 2009)

Jap, das trifft genau mein Problem. Ich finde es ziemlich hässlich, dass sich im Prod. Projekt noch eine Config-File oder eine Klasse befinden muss, die sowas machen muss. 

Auch wenn ich dafür jetzt geschlagen werde: In PHP ist das wesentlich schöner *duck*

Mal sehen, wie ich das machen werde ...

Danke für euere Hilfe =)


----------



## mvitz (19. Okt 2009)

Ansonsten geht wohl nur über eine Konvention und dann den Controller per Reflection laden.


----------



## onemice (19. Okt 2009)

Das wäre mir auch recht. Reflection find ich zwar nicht schön, aber so wie ich gehört hab, fummelt AspectJ am ByteCode der compilierten Klassen rum, dann darf ich ja wohl Reflection benutzen *fg*

Würdest du mir einen Tipp geben, wie ich über die Reflection API z.B. alle Klassen im Paket
"*.controller" bekomme?


----------



## maki (19. Okt 2009)

> Ziel des Frameworks soll es sein, dass man die Jar-File in ein Projekt legt und der Code der Jar-File dann die Klassen des Projekts aufruft. Und eben diese Funktionalität würde ich gerne implementieren, weiß nur nicht genau wie


das ist doch das klassische "Inversion of Control" Prinzip, die Grundlage jedes Frameworks.
Wenn man sich die anderen Frameworks so ansieht, dann geht viel über Vererbung (template pattern) und ähnliches.


----------



## onemice (20. Okt 2009)

Richtig! im Prinzip möchte ein IoC Framework.

Ich sehe mir mal das Template Pattern an und suche mal nach einem weniger komplexen Framework als Spring *g*, wo ich mir das mal ansehen kann.


----------



## JanHH (26. Okt 2009)

"dachte ich, implementiere ich mal ein simples MVC Web Framework" ... "Mein Ziel bei dem Framework ist es, dass das Framework die ganze Arbeit übernimmt und der "End-Entwickler" nur noch die Controller, Models, Views und Helper oder sowas implementieren muss."

Scherzkeks ^^


----------

