# Repository in der Domain-Klasse



## deamon (4. Nov 2009)

Der Artikel Mit Spring und AOP Domänenklassen verwalten beschreibt, wie man Methoden des Repositorys in Domain-Klassen mit AOP verfügbar machen kann. Der grundlegende Gedanke ist, dass man das Repository selbst in ein Domain-Objekt injiziert.

Mir erscheint das aber irgendwie etwas umständlich, zumal es zumindest bei AOP per Proxy auch nicht gerade förderlich für die Performance ist. In dem erwähnten Artikel steht, dass es mit statischen Methoden Probleme geben würde, weil das angeblich der Testbarkeit und Dependency Injection zuwider laufen würde. Aber das sehe ich nicht so, denn man kann auch statische Felder über eine Methode von außen belegen.

Ausgangspunkt ist in meinem Beispiel die Domain-Klasse "Order", die mit statischen Methoden (bzw. hier nur einer statischen Methode) Funktionalitäten bereitstellt, die typischerweise in einem getrennten Service vorhanden sind.


```
class Order {
    
    private static OrderRepository rep;
    
    static void setOrderRepository(OrderRepository r){
        rep = r;
    }
    
    static void findById(int id) {
        rep.findById(id);
    }
    
}
```

Die Klasse Order verlässt sich zum Speichern auf diese Schnittstelle:


```
interface OrderRepository {

	void findById(int id);
	
}
```

... und bekommt zur Laufzeit diese Implementierung injiziert:


```
public class DefaultOrderRepository implements OrderRepository {

	public void findById(int id) {
		System.out.println(id + " gefunden");
	}
	
}
```

Die Injektion läuft folgendermaßen ab:


```
public class Runner {
 
    public static void main(String[] args){
				Order.setOrderRepository(new DefaultOrderRepository());
				Order.findById(12);
    }
    
}
```

Mir erscheint der Ansatz, die Klasse als Verwalter ihrer Instanzen zu verwenden, ziemlich nahe liegend und leicht nachvollziehbar.

Seht ihr Probleme mit diesem Ansatz?


----------



## maki (5. Nov 2009)

> Seht ihr Probleme mit diesem Ansatz?


Ja, ist unschön & unnötig, statische Methoden sind da nicht schön imho, wenn du kein AOP zum injizieren der Repositories willst, dann mach es doch ganz normal über die DI Fähigkeiten von Spring, da spricht doch nichts dagegen.

Ansosnsten ist die Methode findById (egal ob statisch oder nicht) falsch in der Domainklasse, das macht doch das Repository... entweder du entscheidest dich für "Active Record" oder DDD mit Repositories, aber beides mischen ist auf jedenfall voll daneben


----------



## deamon (5. Nov 2009)

Die DI-Fähigkeiten von Spring reichen aber leider nicht aus, da es darum geht, Dienste in Domain-Objekte und nicht in andere Dienste zu injizieren. Man könnte das bei Verwendung von Hibernate auch mit Interceptoren erledigen. Aber abgesehen davon: Was findest du an statischen Methoden an dieser Stelle schlecht?

Zum Thema Active Record vs. DDD mit Repositories: Es stimmt, der Repository-Ansatz wird etwas versteckt und es entsteht eine Mischung aus Active Record und Repository. Die Philosophie dahinter ist, dass die _Klasse_ ihre Instanzen kennt, so wie andernfalls ein Repository die beinhalteten Objekte kennen würde. Im Prinzip ist das der Ansatz von Grails bzw. GORM, der in der Praxis eigentlich recht angenehm zu nutzen und gut verständlich ist.


----------



## maki (5. Nov 2009)

> Die DI-Fähigkeiten von Spring reichen aber leider nicht aus, da es darum geht, Dienste in Domain-Objekte und nicht in andere Dienste zu injizieren. Man könnte das bei Verwendung von Hibernate auch mit Interceptoren erledigen. Aber abgesehen davon: Was findest du an statischen Methoden an dieser Stelle schlecht?


statische Methoden sind in OO meist schlecht 
Jedenfalls verstehe ich deinen Einwand was AOP & Performance betrifft, hast du denn schon gemessen um wieviel langsamer es dann läuft oder bildest du dir das nur ein? 
Letzteres ist meist der Fall bei voreiligen(ungerechtfertigten) Performance Optimierungen, bringt nur Probleme 



> Zum Thema Active Record vs. DDD mit Repositories: Es stimmt, der Repository-Ansatz wird etwas versteckt und es entsteht eine Mischung aus Active Record und Repository. Die Philosophie dahinter ist, dass die Klasse ihre Instanzen kennt, so wie andernfalls ein Repository die beinhalteten Objekte kennen würde. Im Prinzip ist das der Ansatz von Grails bzw. GORM, der in der Praxis eigentlich recht angenehm zu nutzen und gut verständlich ist.


Das Pattern dazu heisst "Active Record", ist imho nur für sehr kleine Projekte geignet, da wird nicht zwischen Domainklassen und DB Zugriff getrennt, also SOC ist verletzt, eine Grundregel der OO., auch testen wird umständlicher.
Jedenfalls ist es vollkommer Quatsch beides zu machen, damit hat man dann weder DDD noch Active Record sondern das schlechteste aus beiden Welten 
Entscheide dich entweder für DDD (dazu gehört noch viel mehr als nur ein Repository in der Entity) oder Active Record, nur dann hat dein Design die Chance sauber & verständlich zu sein, Architektur wird nicht besser wenn man gegensätzliche Ansätze vermischt.


----------



## Noctarius (5. Nov 2009)

Spring AOP nutzt gewöhnlich die normalen Java Proxies die, in Übermenge eingesetzt, tatsächlich etwas langsamer sein können (im Backend wird Reflection genutzt).

Man kann Spring AOP aber auch dazu anhalten die CGLIB ProxyFactory zu nutzen, welche eine Subclass erstellt und zu nativen Java Bytecode kompiliert. Hier gibt es dann nahezu keinen Geschwindigkeitsverlust, da der Aufruf um genau eine Ebene mit dem Bytecode invokeinterface / invokevirtuell erweitert wird.

Aber wie maki schon sagte, meistens sieht man den Geschwindigkeitsverlust nicht und er ist nur in besonderen, zeotkrotoschen Anwendungen, messbar.


----------

