Viele Interfaces

Hey Leute,

wie handhabt ihr es wenn ihr sehr viele Schnittstellen ansprechen müsst und der Sourcecode dadurch immer mit jedem zusätzlichen Interface komplexer wird??
Ich meine, dass sieht auch nicht toll aus wenn eine Klasse drei oder mehr Interfaces bekommt und sie dann immer einzelnd hinzugefügt werden müssen…

Oder kann man sich eine Art Controller-Klasse bauen, die static ist und die ganzen Interfaces beinhaltet und wo man dann mit Getter methoden die Interfaces bekommen kann?
Ist auch irgendwie blöd mit dem static - ich weiß zwar nicht ob es dann irgendwelche negativen Gründe dafür gibt kein static für Interfaces zu benutzen, aber irgendwie sieht das auch nicht richtig aus.

Ich bin ratlos …:ka: bei kleineren Projekten geht das ja noch klar aber bei komplexeren? Wie schafft ihr es, dass der Quellcode dadurch nicht so “komisch”(schlecht lesbar) aussieht?
(besonders wenn man ein Interface erst durch mehrere Klassen durchreichen muss bis die richtige Klasse das zu benötigende Interface bekommt…)

[quote=ShapeForce]Ich bin ratlos … bei kleineren Projekten geht das ja noch klar aber bei komplexeren? Wie schafft ihr es, dass der Quellcode dadurch nicht so “komisch”(schlecht lesbar) aussieht?[/quote]“Separation of concerns”
Je kleiner die Kassen sind und je weniger sie zu tun haben desto weniger Interfaces müssen sie implementieren.

Ich vermute mal dass viele deiner Klassen direkt Listener interfaces implementieren:class MyClass implements ActionListener, MouseListener, WindowListener //...
Sowas vermeide ich, in dem ich entweder anonyme Listener-Implementierungen schreibe oder explitize ListenerImplementierungen in eigenen Klassen.

bye
TT

Da war TT schneller. :slight_smile:

Deine Klasse übernimmt dann einfach zu viele Aufgaben.

Hmmm ok das wird schwierig :wink:

(besonders wenn man ein Interface erst durch mehrere Klassen durchreichen muss bis die richtige Klasse das zu benötigende Interface bekommt…)

Wie kann man das verhindern?

Oder kann man sich eine Art Controller-Klasse bauen, die static ist und die ganzen Interfaces beinhaltet und wo man dann mit Getter methoden die Interfaces bekommen kann?
Ist auch irgendwie blöd mit dem static - ich weiß zwar nicht ob es dann irgendwelche negativen Gründe dafür gibt kein static für Interfaces zu benutzen, aber irgendwie sieht das auch nicht richtig aus.

Was ist daran problematisch das man sie über eine statische Controler Klasse aufruft?

[quote=ShapeForce]Wie kann man das verhindern?[/quote]Hängt vom konkreten Problem und der Architektur ab. Bisher musste ich aber noch kein Interface weiter als durch 3 Klassen weiterreichen.

[quote=ShapeForce;117631]Was ist daran problematisch das man sie über eine statische Controler Klasse aufruft?[/quote]2 Probleme: Singeltons und wieder “Separation of Concerns”

(technische) Singeltons sind der Alptraum in Sachen UnitTest und Wiederverwendung. In Unittests lassen sich solche technischen Singeltons nicht durch Mocks ersetzen und damit hat man auch alle ihre Abhängigkeiten mit an der Backe. Auf der anderen Seite sind logische Singeltons durchaus sinnvoll um beispielsweise Konfigurationen, die sich zur Laufzeit ändern können systemweit bereit zu stellen, aber das sollte dadurch sicher gestellt werden, dass die Objekte, die den Singelton benötigen diesen im Konstruktor übergeben bekommen.

Zum Thema Verantwortlichkeiten: Das Erzeugen von Objekten ist eine eigenständige Aufgabe und sollte an einer zentralen Stelle beim Programmstart und/oder in Factoy-Klassen gemacht werden. Oft wird dasaber in Konstruktoren “nebenbei” mit gemacht. Das Problem: Man sieht von außen die Abhängigkeiten nicht. Wenn die Abhängigkeiten als Konstruktorparameter übergeben werden sieht man, das das Objekt so alles braucht und kann für den Test geeignete Fake-Implementierungen übergeben.

bye
TT

Viele Interfaces an einer Klasse sieht immer ein bisschen nach “ich hätte gern Mehrfachvererbung” aus. Daran ist erst einmal - wenn es der Problemstruktur entspricht - prinzipiell nichts falsch, und mit Java 8 geht das auch in begrenztem Umfang (Default-Methoden erlauben Mixin-Vererbung).

[quote=Landei]“ich hätte gern Mehrfachvererbung” aus. Daran ist erst einmal - wenn es der Problemstruktur entspricht - prinzipiell nichts falsch,[/quote]Dem würde ich prinzipiell widersprechen. Wenn der Wunsch nach Mehrfachvererbung auf kommt habe ih idR. ein Design-Problem.

Ein wichtiges Entwurfsmuster heißt “Favor Composition over Inheritence” Das bedeutet conkret, dass man seine Vererbungshirarchie über Interfaces abbildet und die konkreten Implementierung intern gekapselte Implementierungen der geerbten Interfaces hat, an die sie die Methodenaufrufe weitergibt.

Ich denke, die neuen Möglichkeiten in Java 8 wenden an dieser Stelle nur zu mehr “What the f.ck per minute” führen.

bye
TT

Es kommt eben auf die Problemstellung an, manchmal kann man von Mehrfachvererbung profitieren (ich hatte Fälle, wo es ohne sehr mühsam geworden wäre - und definitiv kein Designproblem vorlag), oft kommt man ohne aus.

Ein Anzeichen dafür, dass man möglicherweise etwas falsch macht, ist, wenn man Interfaces aus ganz verschiedenen Bereichen implementieren muss. Wobei einen die Java-API wegen diverser Jugensünden manchmal dazu zwingt (man denke nur an Serializable, das man heute wohl eher über eine Annotation realisieren würde).

Falls man bemerkt, dass zwei Interfaces oft gemeinsam auftreten, und zwischen ihnen auch inhaltlich eine Verbindung besteht, kann man daraus auch ein gemeinsames Unter-Interface ableiten.

Wie meinst du Interfaces durch mehrere Klassen weiterreichen?
Also üblicherweise habe ich ein Interface und dann verschiedene Implementierungen und nicht umgekehrt.
Und wie schon angesprochen wurde, wenn deine Klasse viele Interfaces Implementiert, dann scheinst du zu versuchen zu viele Verschiedene Aufgaben in deiner einen Klasse zu lösen. Bei uns im Projekt (ca 100k LoC oder anders gesagt >2k classes) haben wir das Problem nicht. Ich würde mir da an deiner stelle mal anschauen, warum sind das verschiedene Interfaces und wenn es Interfaces für Verschiedene Aufgaben sind, dann würde ich dort auch die Klassen aufteilen.

[quote=CyborgGamma]Wie meinst du Interfaces durch mehrere Klassen weiterreichen?[/quote]ungefähr dies:```interface MySingeltonInterface { // };

abstract class BasisKlasse {
private final MySingeltonInterface singelton;
BasisKlasse (MySingeltonInterface singelton){this.singelton=singelton;}
}
class SpezialKlasse extends BasisKlasse {
SpezialKlasse (MySingeltonInterface singelton){super(singelton);}
}
class FlowKlasse {
public void execute(){ new SpezialKlasse(new MySingeltonInterfaceImpl());}
}```bye
TT