# Dependencie Injection und Factory Method



## Rudolf (25. Okt 2012)

Hallo,

ich versuche meine Software qualitativ hochwertig zu halten, daher versuche ich möglichst passende Design Pattern einzusetzen. Jetzt habe ich aber ein Zielkonflikt.

Auf der anderen Seite versuche ich alle Klassen so zu gestalten, dass Klassen, die den Operator new benutzen strikt von Klassen getrennt werden, die kein new einsetzen und die über Konstruktorinjections ihre benötigten Referenzen kriegen. Damit ist es möglich Klassen nach dem Dependencie Injection Pattern leichter wiederzuverwenden. Daraus resultierte bei mir, dass ich irgendwann eine große factory habe, die alle nötigen Objekte erstellt und miteinander referenziert. Aber irgendwie wirkt dieses Konstrukt auf mich auch nicht wirklich nach OOP.

Zusätzlich habe ich von den Google Tech Talks zum Thema OOP gehört, das man beim Objekt-Konstruktor keine Arbeiten durchführen lassen soll. Ist das sinnvoll? Z.b. man möchte ein Objekt erstellen, das JPanel erweitert. Dieses Objekt soll ein vorkonfiguriertes Panel sein. Daher lasse ich das Objekt sich selber im KoNstruktor konfigurieren. Ist das sinnvoll? Weil für jedes Objekt für den gleichen Aufgabenbereich eine eigene Methode erstellen, die die konfiguration durchführt kommt mir auch merkwürdig vor.

Meine Frage ist daher.

Wann und in welchen Zusammenhängen sollte ich den new-Operator einsetzen und wann nicht? Wann ist das Dependencie Injections Pattern nicht mehr sinnvoll? Mit anderen Worten. Wo ist die grenze?


----------



## bygones (25. Okt 2012)

Rudolf hat gesagt.:


> Auf der anderen Seite versuche ich alle Klassen so zu gestalten, dass Klassen, die den Operator new benutzen strikt von Klassen getrennt werden, die kein new einsetzen und die über Konstruktorinjections ihre benötigten Referenzen kriegen. Damit ist es möglich Klassen nach dem Dependencie Injection Pattern leichter wiederzuverwenden. Daraus resultierte bei mir, dass ich irgendwann eine große factory habe, die alle nötigen Objekte erstellt und miteinander referenziert. Aber irgendwie wirkt dieses Konstrukt auf mich auch nicht wirklich nach OOP.


man hat im normalfall ja auch nicht eine Factory die alles macht, sondern eben Factory Klassen die ihre jeweiligen Klassen erstellen.



Rudolf hat gesagt.:


> Zusätzlich habe ich von den Google Tech Talks zum Thema OOP gehört, das man beim Objekt-Konstruktor keine Arbeiten durchführen lassen soll. Ist das sinnvoll? Z.b. man möchte ein Objekt erstellen, das JPanel erweitert. Dieses Objekt soll ein vorkonfiguriertes Panel sein. Daher lasse ich das Objekt sich selber im KoNstruktor konfigurieren. Ist das sinnvoll? Weil für jedes Objekt für den gleichen Aufgabenbereich eine eigene Methode erstellen, die die konfiguration durchführt kommt mir auch merkwürdig vor.


du verwechselst hier "work in constructor" mit objekt initialisierung. Natuerlich kannst du ein Objekt in seinen Konstruktur komplett initialisieren, diese von aussen zu tun ist eher falsch, da man somit keine Kontrolle hat wie sein Objekt konfiguriert wurde.
"No work in constructor" heisst, dass man im Konstruktor nicht den new Operator haben solle, der neue Objekte erzeugt, die keine reinen Datenobjekte sind.
Dein Panel soll zb nicht drin haben [c]new DatabaseConnection()[/c] oder irgend eine andere Logik, weil man eben dann nicht die Referenz per DI setzen kann



Rudolf hat gesagt.:


> Wann und in welchen Zusammenhängen sollte ich den new-Operator einsetzen und wann nicht? Wann ist das Dependencie Injections Pattern nicht mehr sinnvoll? Mit anderen Worten. Wo ist die grenze?


Die Grenze ist da, wo es keinen Zweck mehr erfuellt, wenn es dir keinen Gewinn bringt. Im Grunde sollte man ja seine Unittests immer daneben haben bzw vorher geschrieben haben. Diese zeigen dann einem ob und wie man Code strukturieren sollte. Zb stellt sich dann bei TDD solche Fragen schon gar nicht.

Der new Operator an sich ist nicht das Problem, das Problem ist wann er genutzt wird.
DI ist dann vielleicht nicht sinnvoll, wenn es einen Grund gibt, dass du die Abhaengigkeit nach aussen verstecken willst (auch wenn man dann hier zb ueber Provider gehen kann). Aber das sollte die Ausnahme sein


----------



## Rudolf (25. Okt 2012)

Danke erstmal für die Worte.

Der Mikso Hevery (Mi?ko Hevery) meint in einem seiner Videos von google tech talks zu einem Thema über Testing, dass man im Konstruktor nur die Referenzen initialisieren soll. D.h. überhaupt keine Arbeiten im Konstruktor. Zumindest habe ich ihn so verstanden. Das erscheint mir aber auch nicht sinnvoll zu sein wie bereits gesagt.

bygones, was sagst du zu folgendem Code


```
class LabelFieldNODI {

	private JLabel label = new JLabel();
	private JTextField field = new JTextField();

	public JLabel getLabel() {
		return label;
	}

	public JTextField getField() {
		return field;
	}

}
```

im Gegensatz zu folgendem:


```
public class Factory{

	public static void main(final String[] args) {
		LabelFieldDI labelField = new LabelFieldDI(new JLabel(), new JTextField());
	}
}

class LabelFieldDI {

	private JLabel label;
	private JTextField field;

	public LabelFieldDI(JLabel label, JTextField field) {
		this.label = label;
		this.field = field;
	}

}
```

Wann ist der erste Code sinnvoll, wann der zweite? Der zweite verlangt für jede Nutzung eine entsprechende Factorymethode. Die andere Klasse hingegen ist standalone.

Wann ist welche angebracht?


----------



## maki (25. Okt 2012)

> Der zweite verlangt für jede Nutzung eine entsprechende Factorymethode.


Die Implementierung ist bekannt, und der Konstruktor ist public.

Man braucht also keine Factory.


----------



## bygones (25. Okt 2012)

Rudolf hat gesagt.:


> Danke erstmal für die Worte.
> 
> Der Mikso Hevery (Mi?ko Hevery) meint in einem seiner Videos von google tech talks zu einem Thema über Testing, dass man im Konstruktor nur die Referenzen initialisieren soll. D.h. überhaupt keine Arbeiten im Konstruktor. Zumindest habe ich ihn so verstanden. Das erscheint mir aber auch nicht sinnvoll zu sein wie bereits gesagt.


das hast du falsch verstanden. default zuweisungen oder Zuweisungen die nicht weiterer Abhaengigkeiten erzeugen sind ok



Rudolf hat gesagt.:


> bygones, was sagst du zu folgendem Code


ui code ist immer eine andere Sache. Man sollte nicht stur einem moeglichen Prinzip folgen, sondern sich ueberlegen, was das einen bringt. Warum sollte man in einer UI die 10 Labels hat, alle 10 im Konstruktor mitgeben ? Was fuer ein Vorteil hat dies ? 
DI zeigt seine Macht vor allem im Testen, wie wuerde dir das Testen es erleichtern, 10 Labels reinzureichen, es sind Implementierungen und keine Interfaces, somit kannst du so und so keinen unterschied machen im Test oder in produktion.
Warum sollte ein UI Element seine interne Struktur (seine visuelle) nach aussen preisgeben ?

Alles in allem, wuerde ich nicht den 2. Weg gehen, ausser die entsprechenden Felder sind anderweitig noch von noeten etc.


----------



## Rudolf (25. Okt 2012)

maki hat gesagt.:


> Die Implementierung ist bekannt, und der Konstruktor ist public.
> 
> Man braucht also keine Factory.



Ok aber ist die zweite wirklich der ersten vorzuziehen?

bygones, bei dem Vorschlag von Misko handelt es sich um das gleiche Prinzip wie DRY. Man sollte versuchen sich nicht selber zu wiederholen. D.h. wenn man sieht dass zwei Klassen ähnlich oder gleich sind, bis auf die Initialisierungen, sollte man versuchen die Klassen so zu gestalten, dass man sie über entsprechende Inections benutzen kann. Ist aber eine Klasse absolut individuell braucht man die Injections nicht, richtig?


----------



## maki (25. Okt 2012)

Rudolf hat gesagt.:


> Ok aber ist die zweite wirklich der ersten vorzuziehen?


Ganz klar:
Kommt darauf an.

Wie bygones schon sagte, GUI Elemente per DI zu injizieren kann ziemlich überflüssig sein.


----------

