# Design Dataaccess-Layer: Meinungen, Tipps und Tricks gefragt



## sesam (11. Jan 2013)

Hallo zusammen, 

ich habe gleich ein konkrete Frage aber bin auch an eurer Meinung, Tipps, Tricks insgesamt interessiert. 

Hier nun zunächst die Strukturierung der Anwendung:

Datamodel (reine POJOs) 
---------------------------------------
Dataaccess-Layer (GenericDAO Pattern, aktuell existiert eine JPA implementierung, es gibt eine persistence.xml und eine mapping.xml, der EntityManager wird injected)
---------------------------------------
Business-Layer (SessionBean in die, die entsprechenden DAO injected werden)
---------------------------------------
Service-Layer (JAX-RS services die die Business Methoden mehr oder weniger wrappen, die Session Beans werden hier auch injected)

Das Ganze orientiert sich stark an folgendem Artikel: JPA Implementation Patterns: Data Access Objects | Javalobby

Das Frontend wird komplett mit HTML, JS und CSS implementiert.

Nun zur konkreten Frage. Aktuell werden die DAOs per DI im Business-Layer injiziert. Bei einer Diskussion heute meinte mein Diskussionspartner. Hier wäre es besser Factories zu verwenden um die DAOs zu erzeugen. Wie würdet ihr das machen? Ich sehe nur wenig Vorteile sich um die Instanzierung selbst zu kümmern bzw. eine weitere Abstraktion einzuführen.


----------



## Marcinek (11. Jan 2013)

Sehe kein Unterschied zwischen DI-Context oder Factorys. 

Man könnte hier um so vieles diskutieren, aber nicht, ob man DI oder Factories benutzt.


----------



## nillehammer (11. Jan 2013)

> Nun zur konkreten Frage. Aktuell werden die DAOs per DI im Business-Layer injiziert. Bei einer Diskussion heute meinte mein Diskussionspartner. Hier wäre es besser Factories zu verwenden um die DAOs zu erzeugen. Wie würdet ihr das machen? Ich sehe nur wenig Vorteile sich um die Instanzierung selbst zu kümmern bzw. eine weitere Abstraktion einzuführen.


DI ist sone Sache. Viele Implementierungen bieten die Möglichkeit, es zu nutzen, indem am eine Annotation über ein (meist sogar privates) Feld schreibt. Das ist auf den ersten Blick praktisch. Aber versuch sowas dann mal *ohne* DI-Container zu benutzen. Reine Unittests (im strengen Sinne)kann man da vergessen. Ich implementiere DI in Services deswegen immer über Konstruktor-Injektion. Sprich zu injizierende Werte werden als Konstruktor-Parameter übergeben. Eine etwas schlecherte Variante wäre Methodenparameter-Injection. Bei beiden Varianten kann man aber immerhin bspw. in Unittests die Injizierung über die Parameter selbst vornehmen oder es bei Integrationstests/in Produktion eben dem DI-Cntainer überlassen.

Langer Rede kurzer Sinn: DI ja, aber vorsicht bei direkter Field-Injection!


----------



## sesam (11. Jan 2013)

Naja ich bin was JEE betrifft jetzt kein Experte aber ich bin der Meinung der EJB-Container wird die Instanzierung und ggf. Skalierung sicherlich im Zweifel besser machen als wenn ich in einer Factory die DAO-Instanzen selber erzeuge. 

Der Vorteil eine Abstraktion in Form von Factories einzubauen ist aus meiner Sicht die Technologieunabhängigkeit. Ich mache mich wenn ich die Instanzierung selbst manage nicht abhängig von JEE.

Was wäre denn so ein diskussionswürdiger Punkt?


----------



## nillehammer (11. Jan 2013)

> Naja ich bin was JEE betrifft jetzt kein Experte aber ich bin der Meinung der EJB-Container wird die Instanzierung und ggf. Skalierung sicherlich im Zweifel besser machen als wenn ich in einer Factory die DAO-Instanzen selber erzeuge.


Das glaube ich nicht mal unbedingt. Aber mit DI ist die Erzeugung eben etwas freier gestaltbar (Singleton, oder doch lieber eins für jeden Thread, Pools, was weiß ich), weil konfigurierbar und nicht fest im Code einer Factory implementiert.


> Der Vorteil eine Abstraktion in Form von Factories einzubauen ist aus meiner Sicht die Technologieunabhängigkeit. Ich mache mich wenn ich die Instanzierung selbst manage nicht abhängig von JEE.


Da die Annotationen für DI inzwischen als eigener JSR spezifiziert sind, würde ich es als Standard ansehen. Von JEE ist man da also garnicht mehr abhängig. Und unter der Voraussetzung, dass du keine Field-Injection verwendest, hast Du alles im Code, was Du brauchst, um Dich im Zweifel doch mal selbst um Instanziierung zu kümmern.


----------



## ARadauer (11. Jan 2013)

nillehammer hat gesagt.:


> Aber versuch sowas dann mal *ohne* DI-Container zu benutzen. Reine Unittests (im strengen Sinne)kann man da vergessen. Ich implementiere DI in Services deswegen immer über Konstruktor-Injektion. Sprich zu injizierende Werte werden als Konstruktor-Parameter übergeben.


Ich denke nicht, das Unit Test darauf einfluss haben müssen wie ich meine Daos erzeuge. Man kann ohne Setter oder Konstruktor Injection die entsprechenden Beans per Reflection in den Unit Tests zusammen hängen...

Ich sehen keinen Grund Daos oder Services von Factories erzeugen zu lassen... dazu hat man DI
Falls ein Kollege anderer Meinung ist, sollte er mal ein Spring Buch lesen...


----------



## nillehammer (11. Jan 2013)

ARadauer hat gesagt.:
			
		

> Ich denke nicht, das Unit Test darauf einfluss haben müssen wie ich meine Daos erzeuge. Man kann ohne Setter oder Konstruktor Injection die entsprechenden Beans per Reflection in den Unit Tests zusammen hängen...


Du hast Recht es ist kein *zwingender* Grund. Ich halte Reflection aber ein bischen für Teufelswerk. Vielleicht bin ich da auch zu puristisch...

Was vielleicht neben meiner Abneigung gegen Reflection noch für Konstruktor-/Setter-Injection spricht ist, dass eine Dependency nach außen sichtbar gemacht wird. Man kann es der Klasse also von *außen* ansehen, welcher anderen Services sie sich noch bedient. Obwohl man da sicher auch argumentieren könnte, dass es sich dabei um ein Implementierungsdetail handelt, dass einen Client schlicht nicht zu interessieren hat. Naja, es heißt ja *Diskussions*forum 

In der Kernaussage, dass die Nutzung von DI der Implementierung von Factories vorzuziehen ist, stimmen wir ja überein.


----------



## sesam (11. Jan 2013)

Super vielen Dank Euch allen! Viele Denkanstöße ....

Die Testbarkeit hatte ich tatsächlich noch nicht wirklich bedacht. Aber das ist ein sehr guter und wichtiger Punkt! 

@ARadauer hast Du da Links mit einem Beispiel? Ich kann mir gerade nicht ganz vorstellen wie das in der Praxis mit Reflection aussehen würde.


----------



## stareagle (11. Jan 2013)

Falls für die Dependency Injection CDI genutzt wird, und eventuell weitere Teile des Java EE Stacks, ist Arquillian einen Blick wert. Arquillian erstellt während des Testens ein JAR mit dem Test, der zu testenden Klasse und deren Abhängigkeiten und deployed das ganze in einen Java EE Container und führt die Tests (JUnit oder TestNG) dann innerhalb des Containers aus.

Beste Grüße

Stareagle


----------



## sesam (12. Jan 2013)

Vielen Dank für die Diskussion und die vielen Denkanstöße!


----------

