Interfaces von Interfaces macht das noch Sinn?

DaBe1812

Bekanntes Mitglied
Hi,

ich bin gerade über etwas älteren Code von mir gestolpert und Frage mich jetzt, wie ich den am Besten optimieren könnte. Folgendes ist die Basis:
Ich habe eine Datenbanktabelle "CONFIGURATION" in der, welch Überraschung, Konfigurationen gespeichert sind.
Die ist in etwa so Aufgebaut
Key1
Key2
Key3
Datentyp des Wertes
Eine Spalte pro Datentyp

Anhand von Key1 erkenne ich die Hauptgruppe zu der die Konfiguration gehört und die anderen Keys splitten das entsprechend nochmal auf.

In meiner Anwendung habe ich für Arten (Key1) von Konfigurationen unterschiedliche Klassen gemacht, also z.B. gibt es eine Klasse Mailkonfiguration, damit ich dann darin Methoden, wie getMailserver oder getSmtpPort verwenden kann, wegen der Lesbarkeit des Codes.

Es gibt aber auch eine Menge X an Konfigurationen zu Fremdsystemen, also Key1 ist "FREMDSYSTEM" und Key2 ist dann der Name des Systems. Das ergibt dann eine Konfiguration der Klasse Fremdsystem in der ich dann immer solche Methoden, wie getServer, getPort, getUsername, getPassword habe. Aber der Zugriff auf die Fremdsysteme geht nicht immer über denselben Kanal, also manche sind per REST angebunden, manche per Datenbank, usw. d.h. aktuell habe ich also als Eigenschaften in der Klasse sowas wie Username und Password, und danach noch eine HashMap mit dem "besonderen" Kram.
In der Anwendung heißt das dann, dass ich eine get-Methode habe, der ich quasi den Key3 als Parameter übergebe, damit ich den Value aus dem Map bekomme.
  1. Leidet dadurch die Lesbarkeit
  2. Ist das ganze nicht mehr "sicher" gegen Eingabefehler
Deswegen würde ich das ganze gerne Refactoren. Da ich gerade das Buch "5 Lines of Code" lese, wollte ich gerne Interfaces dafür verwenden, nur ist die Frage, wie viel Sinn das dann macht. Ich bräuchte also ein Interface für RestConfigs, mit Methoden, wie getServer, getPort, getSSL, getUser,... und ein Interface für DB Configs, mit getServer und getDatabase usw. Jetzt habe ich aber auch z.B. schon eine Config, die beides Verwendet, also wir greifen da sowohl per Rest, als auch per Datenbank zu, also müsste ich in den Interfaces die Methoden schon eindeutiger benennen, also getRestUser und getDbUser.

Und dann ist die Frage, ob man das noch weiter spezialisiert, um die Hashmap ganz los zu werden und für jedes Datum, das benötigt wird eine "echte" Methode zu haben? Am Ende des Tages baue ich jeden RestCall ja fast gleich auf. Unterscheiden tun die sich nur in der Art der Authentifizierung (Simple, LDAP,...).
Also macht es Sinn da für alles ein Interface zu bauen, oder sollte man das nicht ganz so tief spezialisieren? Oder ist es an der Stelle besser von einer Klasse zu erben? Aber wie ist das dann, wenn man etwas erweitert?
 

Oneixee5

Top Contributor
Da Konfiguration bekannt sein muss, könnte man ein Enum verwenden:
Java:
public enum SettingsEnum {
    KEY1A_KEY2A_KEY3_1(getFromDb("A", "A","V1", new Setting(0, "default1"))),
    KEY1A_KEY2B_KEY3_2(getFromDb("A", "B","V2", new Setting(1, "default2"))),
    KEY1B_KEY2B_KEY3_1 ...
    ...

    private static int getFromDb(String k1, String k2, String k3, String default) {
        return MyEntityManagerFactory.getEntityManager().findById(new SettingsPk(k1, k2, k3)).orElse(default);     
    }
  
    final Setting value;

    SettingsEnum(Setting setting) {
        this.value = value;
    }
  
    ...
}
Nur mal so in blaue geraten.
* ist nicht schön, kann man besser schreiben, nur so zum reindenken ...
 

DaBe1812

Bekanntes Mitglied
Moin,

scheinbar hab ich entweder recht schlecht beschrieben, oder ich hab wieder die falschen Worte verwendet. Der DB-Teil ist eigentlich abgehakt, den hab ich eigentlich recht sauber gelöst (denke ich).
Mir geht es quasi um den Teil der Geschäftslogik, also (auch nur frei runtergeschrieben):
Java:
public interface RestConfig {
    String getRestUser();
    String getRestPassword();
    String getRestServer();
}

public interface OracleConfig() {
    String getOracleUser();
    String getOracleServer();
    String getOravcleSchema();
}

public class SimpleRestConfig implements RestConfig {
    String username;
    String password;
    String server;
    //getter aus implements
}

public class RestAndOracleConfig implements RestConfig, OracleConfig {
    //Alle getter, von beiden implements
}

Die Frage ist jetzt, ob das so Sinn machen würde? Aktuell gibt es nur eine Klasse für "Fremdsystemkonfiguration" die Benutzername, Passwort und Server hat und der Rest steht dann immer in einer HashMap vund wenn ich dann auf einen dieser Parameter im Code zugreifen möchte, muss ich wissen, wie ich den Schlüssel in der Datenbank genannt habe. Mit der einfachen Implementierung aus meinem Beispiel hätte ich dann nur noch die echten "Spezialfälle" in der HashMap.

Die nächste Möglichkeit wäre, dass ich alle Spezialfälle (aktuell gibt es die nur bei REST) in das Interface rein packe und die bleiben dann einfach bei manchen Configs NULL.

Aber hauptsächlich geht es mir um die Frage, ob ich jetzt eine eigene Klasse für jede Fremdsystem-Konfiguration mache. oder ob der Ansatz mit der generischen Klasse eigentlich okay ist.

Wobei, wenn ich so darüber schreibe, denke ich, dass es für jede Konfiguration eine eigene Klasse geben sollte, weil die eben nie wirklich gleich sind und es hinterher für den nächsten Programmierer absolut nicht sichtbar ist, woher dieser Wert kommt.

Dabei kommt aber direkt die nächste Frage auf:
Zwei Systeme bauen ihre Authentication über die Payload auf. Da geht es dann um Sonderfälle. Die dann am besten in die Config-Klasse packen? Aktuell liegen die nämlich in der Klasse für den RestCall, weil ich da die Config im Zugriff habe.
 

Robert Zenz

Top Contributor
Eigene Klassen fuer diese "Konfiugrationspakete" kann schon sehr gut Sinn machen, den Sinn hinter den Schnittstellen wuerde ich aber eher noch hinterfragen. Grundsaetzlich wuerde ich sagen "Wenn es keine zwei Implementierungen gibt, macht eine Schnittstelle keinen Sinn". So richtig furchtbar finde ich dann wenn jemand "SomethingInterface" und direkt daneben "SomethingImpl" liegen hat, einfach nur Schnittstellen verwenden damit man sagen kann man hat Schnittstellen verwendet ist komplett wertfrei und erzeugt nur zusaetzliche Arbeit und Wartungsaufwand.

Das gesagt, so wie du das beschreibst haette ich mir spontan so etwas vorgestellt:

Java:
public final class ConfigurationProvider {
    public String getString(String key1, String key2) {
        // TODO Query from DB
        // TODO Check type
        // TODO Return value
    }
}

Diese sehr einfache und ueberschaubare Klasse kannst du dann verwenden in deinen Konkreten Konfigurations-Objekten:

Java:
public final class OracleConfiguration {
    private final ConfigurationProvider configurationProvider;
    
    public OracleConfiguration(ConfigurationProvider configurationProvider) {
        super();
        
        this.configurationProvider = configurationProvider;
    }
    
    public String getUsername() {
        return configurationProvider.getString("oracle", "username");
    }
}

Damit hast du keinerlei Abhaengigkeiten, und damit auch weniger Kopfschmerzen.

Mit der einfachen Implementierung aus meinem Beispiel hätte ich dann nur noch die echten "Spezialfälle" in der HashMap.
Die kannst du auch noch los werden in dem du sie in der konkreten Klasse in ein Objekt wandelst.

Java:
public final class ComplexConfiguration {
    // Siehe vorherige Klasse fuer Felder und Konstruktor.
    public ServerDetails getServerDetails() {
        Map<String, String> serverDetailsMap = configurationProvider.getMap("something", "something");
        
        return new ServerDetails(
                serverDetails..get("value1"),
                serverDetails..get("value2"));
    }

    public static final class ServerDetails {
        // TODO Felder und Getter fuer die Werte.
    }
}

Dann hast du quasi fuer alles eine Klasse welche Datenbank-Konfiguration in Java-Objekte umsetzt.

Zwei Systeme bauen ihre Authentication über die Payload auf. Da geht es dann um Sonderfälle. Die dann am besten in die Config-Klasse packen? Aktuell liegen die nämlich in der Klasse für den RestCall, weil ich da die Config im Zugriff habe.
Klingt auch besser. Logik in einer Configuration-Klasse zu haben welche dann Dinge tut ist jetzt nicht so doll ersichtlich. Idealerweise halten die Configuration-Klassen eben nur genau das, die Werte fuer die Konfiguration. Wenn du da dann Logik drinnen hast zum vorbereiten eines Rest-Aufrufs, dann sind das ja eher ConfigurationAndRestCallPreparer. Die Logik fuer den Rest-Aufruf sollte in der Klasse liegen welche fuer den Rest-Aufruf zustaendig ist.

Und dann ist die Frage, ob man das noch weiter spezialisiert, um die Hashmap ganz los zu werden und für jedes Datum, das benötigt wird eine "echte" Methode zu haben?
Das Problem ist halt, du hast die Auswahl zwischen diesen beiden Szenarien:

Java:
Map<String, String> complexRestCallValuesMap = configuration.getMap("something", "something");
restCall.setProperty("blabla", complexRestCallValuesMap.get("thisvalue"));

// Oder

ServerDetails serverDetails = restConfiguration.getServerDetails();
restCall.setProperty("blabla" serverDetails.getThatValue());

Das erste hat den Vorteil dass du dir Tipp- und Wartungsarbeit ersparst, weil du quasi direkt auf die Datenbank-Werte zugreifst, der Nachteil ist dass wenn jemand die Datenbank-Werte aendert, also ein Feld umbenennt, kannst du jede Ecke suchen gehen wo das einschlaegt.

Das zweite hat den Vorteil dass du nur eine Stelle hast (naemlich RestConfiguration) wo sich Aenderungen in der Datenbank niederschlagen, und du kannst diese dort sogar "abfangen" und die restliche Logik bekommt die Aenderungen gar nicht mit. Also zum Beispiel wenn ein Feld von "ServerHost" auf "URL" umbenannt wird, schlaegt das nur an einer Stelle ein und die restlichen Klassen muessen das nicht mal annaehernd wissen. Der Nachteil ist dass du die Struktur doppelt pflegst, einmal in der Datenbank, einmal im Java Code.
 

DaBe1812

Bekanntes Mitglied
Über die Möglichkeit, die Methoden ins System bereit zu stellen und dahinter direkt die Wertebeschaffung zu legen, hatte ich noch gar nicht nachgedacht.
Und ich bin auch kein Freund von diesen 1:1 Beziehungen zwischen einem Interface und einer Klasse. Ich hatte hier einige Projekte übernommen, wo das genau so war, da gab es ein ConfigInterface und dahinter genau eine Implementierung, weil damit dann eine große Ini ausgelesen worden ist. Und später im Code wurde es dann richtig Banane, wenn man einen neuen Wert konfigurierbar machen wollte, dann hat man den Getter erst im Interface anlegen müssen und dann in der Impl.
Ich möchte die Interfaces tatsächlich als solche verwenden. Wenn in Zukunft auf einmal für z.B. Restcalls es wichtig wird zu wissen, auf welchem Port der Endpoint hört, dann kommt ein getPort() in das Interface und dann sind eben alle Klassen unter dem Interface erstmal Rot und ich muss mich darum kümmern, wie ich das jetzt in jeder einzelnen Klasse unter dem Interface löse.
Ich werde dann auf Kurz oder lang wohl komplett von den HashMaps weggehen und dann eben auf die explizite Implementierung prüfen, also in etwa:
Java:
if((Klasse implements Interface) instanceof konkrete Integration) {
    //Tu Dinge
}

Dann kann ich das Problem ConfigurationAndRestCallPreparer-Klasse verhindern, aber in der RestCallerKlasse immer mit dem Interface arbeiten.

Heute erst wieder gesehen, wie wichtig das Refactoring ist, wenn eine Methode fertig ist und übergeben werden soll. Je mehr Entwickler an einer Anwendung arbeiten, um so schlechter wird es, wenn bei einem Modul etwas nicht geht und der Verursacher gerade nicht greifbar ist.
 

Robert Zenz

Top Contributor
Ich möchte die Interfaces tatsächlich als solche verwenden. Wenn in Zukunft auf einmal für z.B. Restcalls es wichtig wird zu wissen, auf welchem Port der Endpoint hört, dann kommt ein getPort() in das Interface und dann sind eben alle Klassen unter dem Interface erstmal Rot und ich muss mich darum kümmern, wie ich das jetzt in jeder einzelnen Klasse unter dem Interface löse.
Dafuer kenne ich jetzt deine Applikationsstruktur nicht um das beurteilen zu koennen ob sich das auszahlt, aber kann sehr gut sein.

Ich werde dann auf Kurz oder lang wohl komplett von den HashMaps weggehen und dann eben auf die explizite Implementierung prüfen, also in etwa:
Auf konkrete Implementierungen zu pruefen ist immer so eine Sache, eigentlich sollte es nicht notwendig sein, aber ganz verhindern kann man es auch nicht immer.

Vielleicht ist hier ein Hinweis auf Eclipse hilfreich, die verwenden das Prinzip von "Interface Extensions", also die haben eine Basis-Schnittstelle, und dann mehrere Erweiterungen dazu welche implementiert werden koennen oder auch nicht:

Java:
public interface BaseFunctionality {
    // TODO
}

public interface BaseFunctionalityExtension1 {
    // More stuff.
}

public interface BaseFunctionalityExtension2 {
    // More stuff.
}


if (functionality instanceof BaseFunctionalityExtension2) {
    // Do something with it here.
}
 

DaBe1812

Bekanntes Mitglied
Auf konkrete Implementierungen zu pruefen ist immer so eine Sache, eigentlich sollte es nicht notwendig sein, aber ganz verhindern kann man es auch nicht immer.
Die alternative dazu wäre ja, wenn ich das, was ich eigentlich nur in der konkreten Klasse verwenden würde, ins Interface baue und dann in allen Implementierungen "null" oder Ähnliches zurück gebe und nur in der einen Klasse, wo ich es brauche dann eine "echte" Antwort.
Also irgendwie so:
Java:
public interface DasInterface {
    String getUser();
    String getPassword();
    int getBrauchIchNurIn1();
    int getBrauchIchNurIn2();
}

public class impl1 implements DasInterface {
    String getUser() { return user; }
    String getPassword() { return password; }
    int getBrauchIchNurIn1() { return wert1; }
    int getBrauchIchNurIn2() { return null; }
}

public class impl2 implements DasInterface {
    String getUser() { return user; }
    String getPassword() { return password; }
    int getBrauchIchNurIn1() { return null; }
    int getBrauchIchNurIn2() { return wert2; }
}

Also in der konkreten Verwendung erwarte ich für Klasse2 ja garnicht, dass sie an der Stelle vorbei kommt, wo Wert1 gebraucht wird, bzw. prüfe ich ja, ob Wert1 null ist und wenn ja, dann muss eben was anderes passieren.
Vorteil wäre, dass wenn sich er Webservice für impl1 ändert, und ich Wert2 bräuchte, dann könnte ich den einfach einbauen.

Dafuer kenne ich jetzt deine Applikationsstruktur nicht
Also nur als kleinen Background, ich hatte angefangen mit 4 externen Systemen, die ich abfrage und bin mittlerweile bei 8 und das Potenzial an Fremdsystemen, die ich auslesen könnte ist hier noch lange nicht ausgereizt. Also macht ein Interface hier evtl. schon Sinn, wenn es bisher nur eine Implementierung dafür gäbe.

Das Eclipse-Beispiel werde ich mir nochmal durch den Kopf gehen lassen, das wäre evtl. eine Überlegung wert.
 

Robert Zenz

Top Contributor
Die alternative dazu wäre ja, wenn ich das, was ich eigentlich nur in der konkreten Klasse verwenden würde, ins Interface baue und dann in allen Implementierungen "null" oder Ähnliches zurück gebe und nur in der einen Klasse, wo ich es brauche dann eine "echte" Antwort.
Ja, das ist uebler, da stimme ich dir zu, weil dann muss man immer die "leer" Methoden mitschleifen.

Also nur als kleinen Background, ich hatte angefangen mit 4 externen Systemen, die ich abfrage und bin mittlerweile bei 8 und das Potenzial an Fremdsystemen, die ich auslesen könnte ist hier noch lange nicht ausgereizt. Also macht ein Interface hier evtl. schon Sinn, wenn es bisher nur eine Implementierung dafür gäbe.
Das kommt darauf an wie gleich die Systeme aufgerufen werden. Es macht keinen Sinn, wuerde ich behaupten, fuer 50% eine generische Klasse zu haben und fuer die anderen 50% eine spezifische. Da wuerde ich Gleichheit unter den Implementierungen bevorzugen und immer eine konkrete Klasse machen, weil sonst muss man immer schauen wie wo was wenn sich etwas aendert.

Eventuell macht es auch Sinn diese Initialisierung dann wegzukapseln aus deiner eigentlichen Logik mit Hilfe von Fabriken. Also statt:

Java:
Configuration configuration = getSpecificServiceConfiguration();
Service service = new SpecificService();
service.init(configuration);

Dann eben:

Java:
Service service = SpecificServiceFactory.getService();

Weil dann kannst du schoen spezifische Klassen und Initialisierungen machen fuer jeden einzelnen Dienst, aber deiner Hauptlogik ist das egal.
 

KonradN

Super-Moderator
Mitarbeiter
Sorry, aber ist das nicht ein klares Beispiel, dass gegen das Interface Segregation Principle verstoßen wurde?

In the field of software engineering, the interface segregation principle (ISP) states that no code should be forced to depend on methods it does not use.[1] ISP splits interfaces that are very large into smaller and more specific ones so that clients will only have to know about the methods that are of interest to them.

Ich kenne die genauen Anforderungen nicht und habe den ganzen Thread auch nicht im Detail verfolgt. Und ich will auch niemandem irgend welche Meinungen aufdrängen, aber #7 triggert mich denn das ist zumindest ein "Code Smell" in meinen Augen und das Design sollte man prüfen.

Erst einmal bezüglich Interface Segregation Principle:

Du hast nicht 1 Interfaces sondern 3:
Java:
public interface DasInterface {
    String getUser();
    String getPassword();
}

public interface DieErweiterungFuer1{
    int getBrauchIchNurIn1();
}

public interface DieErweiterungFuer2 {
    int getBrauchIchNurIn2();
}
    
public class impl1 implements DasInterface, DieErweiterungFuer1 {
    String getUser() { return user; }
    String getPassword() { return password; }
    int getBrauchIchNurIn1() { return wert1; }
}

public class impl2 implements DasInterface, DieErweiterungFuer2 {
    String getUser() { return user; }
    String getPassword() { return password; }
    int getBrauchIchNurIn2() { return wert2; }
}

Und jetzt wird man sagen: "Das ist doof - dann muss ich ja mehr prüfen, a.la. ist es DieErweiterungFuer1 um dann darauf die Methode aufzurufen." Aber so Checks muss es meist eh geben, nur eben bei Dir ggf. eine null Prüfung. Incl. der Gefahr, dass du das vergisst und dann eine NPE bekommst (Oder du hast einen Optional oder einen alternativen Wert, den Du abprüfst).

Und hier ist auch immer die Frage, woher die Werte kommen. Müssen diese so spezialisiert / konkret sein?

Dir geht es um Authentication. Dann hast Du halt eine Map<String,String> additionalParameter. Oder wenn Dich das so stört, dann kannst Du es entweder per Vererbung weiter ausbauen (Dann hast Du einen ConfigKey, der halt auch einem Typ festlegt und so und dann ein ConfigValue mit irgendwelchen zusätzlichen Eigenschaften.) Oder Du baust das auf als ein eigenen Typ. Dann hast Du halt etwas wie
public interface AdditionalParameter { } (oder class - egal) und das kannst Du dann haben. Denn zu der Konfiguration "KonradsSpezialAnmeldeverfahrenParameter" gehört ja auch die Klasse KonradsSpezialAnmeldeverfahren das dann mein hoch spezielles Anmeldeverfahren macht und dafür eben eine Instanz von KonradsSpezialAnmeldeverfahrenParameter haben möchte.

Sprich: Die Frage stellt sich dann auch, in was für eine Richtung man es treiben möchte. Aber im Augenblick würde ich eher in die Richtung Map<String,String> tendieren, denn das ist ja auch, was man z.B. von typischen application.properties Dateien kennt.

Wenn Du das XML in einer flachen Struktur haben willst (also die Map nicht noch einmal eine Ebene abgesetzt sein soll), dann wären vermutlich eigene Serializer / Deserializer notwendig. Die sollten aber nicht schwer zu schreiben sein.
 

DaBe1812

Bekanntes Mitglied
Das kommt darauf an wie gleich die Systeme aufgerufen werden. Es macht keinen Sinn, wuerde ich behaupten, fuer 50% eine generische Klasse zu haben und fuer die anderen 50% eine spezifische.
Naja, also die "Monster" habe ich glaube ich weg, das sind die externen Tools, die per WSDL oder direktem Datenbankzugriff angebunden sind. Alles andere sind Anbindungen per Rest und da kann man die Config in bestimmten Punkten vereinheitlichen, weil das brauche ich bei jedem RestCall:
Java:
public interface GeneralRestConfig() {
    String getServer();
    int getPort();
    boolean isSsl();
    String getUser();
    String getPassword();
}
Und konkret verwende ich aktuell die "variablen Zusatzparameter" in der Weise:
Java:
public String buildCommandLoginPayload() {
    Integer mandant = REFSYSCONFIG.get("MANDANT");
    String right = REFSYSCONFIG.get("RIGHT");
    JSONObject payload = new JSONObject();
    payload.put("user", USERNAME);
    payload.put("password", PASSWORD);
    payload.put("manId", mandant);
    payload.put("userGroupName", right);
    return payload.toString();
}

Also die REST-Tools unterscheiden sich schon in der Art und Weise, wie man sich anmeldet. Mal baue ich eine Payload, mal authentifiziere ich mich einmalig und arbeite dann mit einem Token. Dann gibt es noch die, die einfach über die SimpleAthentication bei jedem Aufruf authentifiziert werden.
Also in dem konkreten Beispiel brauche ich zusätzlich die Konfigurationen Mandant und Right. Aber das brauche ich nur in einer Implementierung.
REFSYSCONFIG wäre dann in dem Fall eine Implementierung von RestConfig, aber an der Stelle müsste ich dann in CommandConfig casten, damit ich eine getMandant() und getRight() nutzen kann.

@KonradN: ja, das ist definitiv ein CodeSmell, sollte ja auch nur nochmal zeigen, dass ein Interface, das alle Methoden vorhält, die evtl. mal gebraucht und dann mal wieder nicht gebraucht werden, eigentlich Mist ist.

Jetzt dreht sich natürlich alles in meinem Gehirn, bzw. vielleicht hast du mich auch abgehängt. Gemäß deines Beispiels gilt, dass Implementierung1 und Implementierung2 beide DasInterface Implementieren, also kann ich den Konstruktor der die Restverbindung bauen soll so bauen:
Java:
public ApacheHttpClientIntegration(DasInterface config) {
    SERVER = config.getServer();
    USERNAME = config.getUser();
    PASSWORD = config.getPassword();
    SSL = config.isSsl();
    PORT = config.getPort();
    this.config = config;
}
Aber in meiner Methode buildCommandLoginPayload(), weiß das System ja nicht, dass in dem Fall this.config auch DieErweiterungFuer1 implementiert. D.h. doch dass es an der Stelle besser wäre direkt auf die konkrete Klasse zu prüfen (instanceof) und für den Sonderfall kein zusätzliches Interface zu bauen?
Zumindest denke ich, dass zukünftige Entwickler an der Stelle direkt sehen könnten, dass diese Strecke nur funktioniert, wenn es eine konkrete Klasse ist.
 

KonradN

Super-Moderator
Mitarbeiter
D.h. doch dass es an der Stelle besser wäre direkt auf die konkrete Klasse zu prüfen (instanceof) und für den Sonderfall kein zusätzliches Interface zu bauen?
Ja, das ist prinzipiell richtig. Die Frage ist halt aus meiner Sicht: Wird es mehrere Implementierungen geben bzw. kann es diese geben?
Wenn Du das mit ja beantwortest, dann macht ein Interface Sinn.

Wenn aber klar ist: Da wird es nicht mehrere Implementationen geben, dann macht da auch kein Interface Sinn und man würde nur die eigentlichen Implementierungen haben.

Und die Frage ist, was Du wo implementieren willst. Ich verfolge oft eine Art Datenbasierten Ansatz. Dann hast Du halt Klassen, die irgendwelche Daten beinhalten. Das kann dann tatsächlich einfach eine Klasse AuthenticationData sein. Da wäre also gar kein Interface.

Und dann hast Du etwas, dass eine Authentication durchführt. Das kann dann ein Interface sein, ggf. sogar ein funktionales. Es wird dann z.b. ein authorize(AuthenticationData) Methode bereit gestellt. Dann hast Du da also konkretes Verhalten in einer Klassenstruktur - also so wie beim Strategy Pattern.

Dann hättest Du also Deine Anwendung, die an einer Stelle eine Strategie zur Anmeldung kennt und aufrufen kann und dazu halt relativ universell Daten vorhalten kann.

Bezüglich zu dem technischen "wie":
Aber in meiner Methode buildCommandLoginPayload(), weiß das System ja nicht, dass in dem Fall this.config auch DieErweiterungFuer1 implementiert.
Wenn Du eine spezielle Implementierung hast, dann erwartest Du das halt auch. Du kannst also in deinem Code das jederzeit überprüfen:

Java:
public ApacheHttpClientIntegration(DasInterface config) {
    SERVER = config.getServer();
    USERNAME = config.getUser();
    PASSWORD = config.getPassword();
    SSL = config.isSsl();
    PORT = config.getPort();
    this.config = config;
    
    if (config instanceOf MySpecificConfig myspecificConfig) {
        mySpecivifConfigDetail = myspecificConfig.getMySpecificConfigDetail();
    } else {
        throw new MyInvalidConfigurationException("AppacheHttpClientConfiguration requires a MySpecificConfig configuration!");
    }
}

Aber wie gesagt: Das würde ich gar nicht erst so haben. Das Interface sehe ich nicht einmal als notwendig an. Da reicht doch eine Klasse aus, die skizziert so ist:
Java:
public class AuthenticationConfig {
    private String username;
    private String password;
    private Map<String, String> additionalConfig;
    
    // ....
}

Wobei ich da bei username / password schon Probleme sehe, denn das könnten ja auch clientId und clientSecret sein (nur als Beispiel). Klar könnte man sowas auch in einer Config als username / password durchgehen lassen, aber das finde ich immer unschön...

Aber da sollte dann evtl. auch @Robert Zenz einmal kurz sagen, ob ich hier nicht evtl. auf dem Holzweg bin und ich evtl. wichtige Dinge übersehe. Nicht, dass ich das alles viel zu einfach und unproblematisch sehe und Dich da jetzt sozusagen vom rechten Weg abbringe.
 

DaBe1812

Bekanntes Mitglied
Also ich habe gerade ein wenig Zeit im Projekt, deswegen eskaliere ich gerade so richtig, jetzt wollte ich mich in dem Zuge noch um ein Schichten-Problem kümmern.
Ich habe die Entität AtcServerConfiguration, die das Abbild aller Konfigurationen auf der Datenbank darstellt.
Darauf müsste ja jetzt eine Klasse stehen, die mit unterschiedliche Datensätze vom Typ AtcServerConfiguration oder Listen von AtcServerConfiguration aus der Datenbank holt.
Und am Ende soll meine neue Klasse der Konfiguration stehen.
Muss da nicht dazwischen noch eine Klasse stehen, die mir ein Objekt der Klasse baut?
Also auf dem DatenbankLayer halte ich doch eigentlich nur die Entitäten und Klassen, die sich damit beschäftigen diese aus der Datenbank raus und wieder rein zu bekommen. Idealerweise bleibt man dabei bei den reinen Entitäten, oder Klassen, die in Java vorhanden sind (String, List, Map,...).
Die nächste Schicht macht dann daraus Objekte, die ich für meine Business-Logik brauche. Und das wäre doch jetzt die Schicht, die ich meine, oder?
Das wäre doch das, was @Robert Zenz in Post #8 beschrieben hat mit
Java:
Service service = SpecificServiceFactory.getService();
Oder verkompliziere ich das gerade wieder viel zu sehr im Kopf?
 

DaBe1812

Bekanntes Mitglied
So, hab jetzt die ersten Schritte gemacht, allerdings gefällt mir das Füllen des Objekts noch nicht, gäbe es da eurer Meinung nach, vielleicht eine schönere Lösung?
Java:
public class AmConfig implements RestConfigInterface {
    //Für die Methoden aus dem Interface
    private String restUser;
    private String restPassword;
    private String restServer;
    private int restPort;
    private boolean restSsl;
    //Eigenschaft, die nur auf AM zutrifft
    private boolean useForHardwareImport;

    @SuppressWarnings("unchecked")
    public AmConfig(List<AtcServerParameter> parameter) {
        for(AtcServerParameter par : parameter) {
            String key = par.getKey3().toUpperCase();
            Object value = par.getValue();
            switch(key) {
            case "PASSWORD":
                this.restPassword = (String) value;
                break;
            case "PORT":
                this.restPort = (int) value;
                break;
            case "SERVER":
                this.restServer = (String) value;
                break;
            case "SSL":
                this.restSsl = (Boolean) value;
                break;
            case "USER":
                this.restUser = (String) value;
                break;
            case "USE_FOR_HW_IMPORT":
                this.useForHardwareImport = (Boolean) value;
                break;
            }
        }
    }
//Getter-Methoden
}

Befüllen tu ich die so:
Java:
@ApplicationScoped
public class ConfigurationService {
    @Inject private AtcServerParameterInterface atcServerParameterInterface;
    
    public AmConfig getAmConfig() {
        List<AtcServerParameter> parameters = atcServerParameterInterface.loadConnectorConfig(ReferenceSystem.AM);
        AmConfig amConfig = new AmConfig(parameters);
        return amConfig;
    }
}

Und die Daten kommen aus der Datenbank so:
Java:
@ApplicationScoped
public class AtcServerParameterInterface {

    @Inject EntityManagerProvider emp;

    public List<AtcServerParameter> loadConnectorConfig(ReferenceSystem refSys) {
        EntityManager em = emp.getEntityManager();
        TypedQuery<AtcServerParameter> query = em.createNamedQuery("AtcServerParameter.connectorParameter", AtcServerParameter.class);
        List<AtcServerParameter> resultList = query
                .setParameter("REFSYS", refSys.name())
                .getResultList();
        return resultList;
    }
}

Ich habe halt gelesen, dass Switch-Case eher vermieden werden sollte, aber an der Stelle leuchtet mir nicht ein, wie ich das machen sollte.

Und da es mir beim kopieren gerade auffällt, die getValue-Methode im AtcServerParameter geht da auch ein generischer Ansatz?
Java:
public Object getValue() {
    switch(datatype) {
        case BOOLEAN:
            return booleanValue;
        case INTEGER:
            return integerValue;
        case PASSWORD:
        case STRING:
            return stringValue;
        case LIST:
            return Arrays.asList(stringValue.split(","));
        case MAP:
            return JsonHelper.toLinkedMap(stringValue);
        case SQL:
            return clobValue;
        default:
            return null;
    }
}

Für die alte Config hatte ich da mal etwas geklaut gehabt:
Java:
public class ReferenceSystemConfig {
    private Map<String, Object> values;

    public ReferenceSystemConfig(Map<String, Object> configMap) {
        values = configMap;
    }

    @SuppressWarnings("unchecked")
    private <VALUE_TYPE> VALUE_TYPE getWithCast(String key) {
        if (values.containsKey(key)) {
            return (VALUE_TYPE)values.get(key);
        }
        return null;
    }

    public String getUsername() { return getWithCast("USER"); }
    public String getPassword() { return getWithCast("PASSWORD"); }
    public String getServer() { return getWithCast("SERVER"); }
    public Integer getPort() { return getWithCast("PORT"); }
    public boolean isSsl() { return getWithCast("SSL"); }
    public Map<String,String> getFieldMapping() { return getWithCast("FIELDMAPPING"); }
    public <VALUE_TYPE> VALUE_TYPE get(String key) { return getWithCast(key); }
}

Allerdings sollen die Passwörter, sobald die Passwortdatenbank sauber läuft, verschlüsselt in der DB abgelegt werden, da bin ich mir aber auch noch nicht sicher, wann ich die entschlüssele, also schon bei der Übertragung ins Objekt, oder erst direkt bei der Verwendung.
 

Joreyk

Mitglied
nimm halt irgendeinen serialisierer her der dir die klassen und input datei mappt damit du die nicht selber auflösen musst

die datei wrid doch irgendeinem standartisierten format entsprechen.. und da schaust halt nach einem serialisierer der das macht
 

DaBe1812

Bekanntes Mitglied
Hi, funktioniert das mit dem Serialisierer tatsächlich auch mit Datenbankwerten?
Bei meinen Standalones mach ich das tatsächlich so und hab alles auf ein schönes YAML-Format umgestellt, aber dass das auch bei Datenbanken funktioniert, war mir nicht bewusst.
Wie würde ich das in meiner Struktur dann am besten machen?
 

Joreyk

Mitglied
für datenbanken gibts es das konzept ORM: Object Relational Mapping,

da wird geschaut dass die tabellen so aussehen dass sie zu den objekten passen und der orm serialisierer kann halt dann objekte hin und her schicken

oder falls es die bibliothek kann, dann werden klassen aus den tabellen erzeugt... also ja es geht
man muss nur gucken was man wo und in welchem format haben will

java hat für jeden schmarn eine bibliothek also versuch nicht alles von 0 aufzubauen, der ganze code den du dir durch bibliotheken rein sparst musst du nicht selber maintainen


zb ich hatte ja wegen jackson gefragt, ich musste die input/output datei von yaml json und xml lesen und schreiben können
ich bin doch nicht so wahnsinnig da 3 mal einen eigenen serialisierer zu schreiben ... das mapping übernimmt jackson also sind meine daten klassen immer gleich und das lesen und schreiben wird mir eh abgenommen
 

DaBe1812

Bekanntes Mitglied
Okay, jetzt musste ich erstmal ORM googeln, weil ich dachte ich würde es missverstehen.
Also ich verwende schon EclipseLink (Vorgabe) aber es gibt einen Unterschied zwischen dem DataLayer und dem LogicLayer. Die Entity sieht so aus:
Java:
public class AtcServerParameter {

    private static final Logger LOG = LogManager.getLogger(AtcServerParameter.class);
    
    @Id
    @Column (name = "ID")
    private String id;
    
    @Column(name = "KEY1")
    private String key1;
    
    @Column(name = "KEY2")
    private String key2;
    
    @Column(name = "KEY3")
    private String key3;
    
    @Column(name = "KEY4")
    private String key4;
    
    @Column(name = "KEY5")
    private String key5;
    
    @Column(name = "DATATYPE")
    @Enumerated(EnumType.STRING)
    private ParameterDatatype datatype;

    @Column(name = "STRING_COL")
    private String stringValue;
    
    @Column(name = "INTEGER_COL")
    private Integer integerValue;
    
    @Column(name = "DOUBLE_COL")
    private Double doubleValue;
    
    @Column(name = "BOOLEAN_COL")
    private Boolean booleanValue;
    
    @Column(name = "DATE_COL")
    private Timestamp timestampValue;

    @Lob
    @Column(name = "CLOB_COL")
    private String clobValue;

    public Object getValue() {
        switch(datatype) {
        case BOOLEAN:
            return booleanValue;
        case INTEGER:
            return integerValue;
        case PASSWORD:
        case STRING:
            return stringValue;
        case LIST:
            return Arrays.asList(stringValue.split(","));
        case MAP:
            return JsonHelper.toLinkedMap(stringValue);
        case SQL:
            return clobValue;
        default:
            return null;
        }
    }
    //Getter und Setter und eine generische setValue(Object value) Methode
}

Das Objekt, was ich in meiner Geschäftslogik brauche sieht aber so aus:
Java:
public class FiServiceConfig implements RestConfigInterface, ReferencesystemConfigInterface, Pingable {
    
    private String restUser;
    private String restPassword;
    private String restServer;
    private int restPort;
    private boolean restSsl;
    
    private Map<String, String> fieldMapping;

    @SuppressWarnings("unchecked")
    public FiServiceConfig(List<AtcServerParameter> parameter) {
        for(AtcServerParameter par : parameter) {
            String key = par.getKey3().toUpperCase();
            Object value = par.getValue();
            switch(key) {
            case "PASSWORD":
                this.restPassword = (String) value;
                break;
            case "PORT":
                this.restPort = (int) value;
                break;
            case "SERVER":
                this.restServer = (String) value;
                break;
            case "SSL":
                this.restSsl = (Boolean) value;
                break;
            case "USER":
                this.restUser = (String) value;
                break;
            case "FIELDMAPPING":
                this.fieldMapping = (Map<String, String>) value;
                break;
            }
        }
    }
    //Getter aus den Interfaces
}

In meinen Standalone-Anwendungen habe ich auch eine Automatik dafür, und alle meine Config-Files auf YAML umgestellt (war der schönste Converter, den wir im lokalen Nexus hatten).

Da ich aber die Config-Werte gerne über die Oberfläche warten können möchte, ohne dass man auf Konventionen aufpassen muss, habe ich eben jedes Attribut in seiner eigene Zeile.
 

Joreyk

Mitglied
Java:
    public FiServiceConfig(List<AtcServerParameter> parameter) {
        for(AtcServerParameter par : parameter) {
            String key = par.getKey3().toUpperCase();
            Object value = par.getValue();
            switch(key) {
            case "PASSWORD":
                this.restPassword = (String) value;
                break;
            case "PORT":
                this.restPort = (int) value;
                break;
            case "SERVER":
                this.restServer = (String) value;
                break;
            case "SSL":
                this.restSsl = (Boolean) value;
                break;
            case "USER":
                this.restUser = (String) value;
                break;
            case "FIELDMAPPING":
                this.fieldMapping = (Map<String, String>) value;
                break;
            }

nach keys zu switchen schaut aber nicht richtig aus

egal was du hast, es sollte die fähigketi besitzen das in objekte aufzulösen ansonsten ist das was du hast relativ useless
 

DaBe1812

Bekanntes Mitglied
Danke dafür, das war meine Eingangserkenntnis, dass ich von dem geswitche weg möchte, weil es instabil ist. Aber ich will auch nicht für jede Art der Config eine eigene Tabelle machen. Es muss doch so einen Mittelweg geben und der kann auch nicht sein, dass ich eine Tabelle habe mit den Spalten
  • STRING_1...10
  • INTEGER1...10
  • ...
Nur damit ich dann mein Objekt von der JPA parsen lassen kann.
Ich brauche also etwas, dass in drei Welten funktioniert:
Zum einen die Anwendungslogik, wo ich mit Befehlen wie getPassword() und getServer() anhand der Methode sehen kann, was ich gerade tue und jeder Entwickler, der eine Klasse mit den Objekten warten muss sieht, was gemacht wird.
Dann muss das Ganze über die Oberfläche einstellbar sein, ohne dass der User verstehen muss, wie ein ordentliches JSONArray aufgebaut ist, um das in einem Überdimensionalen Textfeld zu pflegen.
Und zu guter Letzt muss es auf der Datenbank anständig aussehen, d.h. ich muss mit einfachen Where-Bedingungen die Konfiguration finden können, die ich brauche, weil sie vielleicht so vermurkst ist, dass die Anwendung so nicht starten kann.

Und das alles soll so gehen, dass das System selbst entscheiden kann, welcher Datensatz an welche Stelle des Objektes gehört? Vielleicht sind das einfach zu viele Wünsche auf einmal, oder man muss hier einen Tod sterben.

Aber wie schon eingangs gesagt und zwischenzeitlich bemerkt:
SWITCH-CASE ist gefährlich, weil wenn ich mich in der Datenbank mal bei den KEYWORDS vertippe, dann ist das System lahmgelegt.
 

Joreyk

Mitglied
Java:
STRING_1...10
INTEGER1...10
was ist denn das für ein format? kriegst du das so ?

also 1.
wo speicherst du was ab json .. db ... was nu?

dann schreib doch pseudo code jsons, eine pseudo tabelle wie das aussehen KÖNNTE überall
wenn du glücklich bist damit dann überlegst du mal wie das in java aussehen könnte



zum bleistift
Code:
class {
    string password
    string user
}

{
    "password" : asdf
    "user" : bob
}

| user | password
| bob  | asdf

und dann holst du bibliotheken die dir das in jede richtung mappen
und dann pflanscht du die annotationen an deine java klasse bis jeder mapper das hinkriegt

es gibt mapper für json , es gibt mapper für datenbanken
wenn das erzwungene eclipse link das nich hinkriegt dann ist es useless


mach doch mal prototypen, auf einem leeren papier kann man keine 10000 seiten geschichte erfinden


ob dann der mapper bleibt oder nicht ist doch komplett egal
erstmal das groß konzept hinhauen


dann mit testen anfangen, und wenn nötig auch ein neues projekt, der prototyp ist erstmal da
teste das groß konzept nicht die implementierung

ob du die verbindung von json oder db kriegst ist doch irrelevant für das groß konzept
ein test wäre "nimm die verbindung, und mach output"
ob die verbindung von json oder db oder sonst was eingelesen wird ist doch egal für das groß konzept

das sind die tests die jahre nach dem sie geschrieben wurden noch unverändert bleiben, weil sie nicht die implementierung testen sondern das konzept, wer sagt denn dass du nächstes jahr noch json hast? dann wäre der json test auf rot.. und nu? du hast einen test gebrochen und die korrigierung wäre es den test zu löschen? dann war der test im ansatz schon falsch...so mal als beispiel


prototyp ideen sind immer gut, in dem projekt wo ich aktuell bin wurde 2 jahre ein prototyp geschrieben, der wurde als gut angesehen weils konzept gepasst hat, der code wurde verworfen und von neuem angefangen um das sauber aufzusetzen

nach einem halben jahr hat man jetzt genauso viel wie im prototyp aber mit allem vertestet und der sicherheit dass es ein gutes konzept ist von dem was man überhaupt will, zuerst überlegen und denken zahlt sich aus
 
Zuletzt bearbeitet:

DaBe1812

Bekanntes Mitglied
Okay, ich speichere, wie schon ganz oben und in jedem weiteren Post erwähnt meine Konfiguration für diesen Konkreten Fall um den es mir hier geht, in einer Datenbank ab.
Das YAML Thema war lediglich ein dir zustimmen, weil ich das in anderen Projekten so mache, das sind aber alles einfache Java-Tools für einfache Aufgaben, die mehr oder minder manuell ausgeführt werden.

Das Thema mit String1..10 sollte einfach darstellen, dass ich um das ganze einfach mappen zu lassen über den PersistenceLayer eine Tabelle machen könnte mit den Spalten

ConfigNameString1String2String3Integer1Integer2Integer3
ConfigAUserNamePasswortServerPort
Und dann könnte ich einfach jede Config als Entität auf dieser Tabelle machen und dann das ganze zuweisen.

wenn das erzwungene eclipse link das nich hinkriegt dann ist es useless
Was genau sollte denn ein ORM mit meinem Datenmodell hin bekommen? Es gibt 5 Zeilen einer Tabelle, die einen Key haben und der Wert in einer von fünf Spalten steht, welche sich aber glücklicherweise über eine weitere Spalte finden lassen.

Mein Verständnis von einem ORM ist, dass es automatisch die Werte EINER Zeile auf die Felder einer Klasse mappt und das Tut EclipseLink genauso gut, wie Hibernate und JPA. Nach deinem Modell hätte ich pro Config Klasse eine Tabelle, dann wäre das mit den ORM Mitteln möglich, aber das würde bei meinen ganzen verschiedenen Configs, die es im System gibt bei ca. 20 Tabellen raus kommen und ca. 15 davon hätten nur eine Zeile.

Das Modell hatten wir mir drei Mann so erarbeitet und das läuft auch schon seit Jahren in der Anwendung, das heißt aber nicht, dass es nicht optimiert werden kann.
Und ich habe letzte Woche die komplette "alte" Config gegen die neuen Klassen getauscht und außer einzelner Aufrufe, die ich jetzt direkt mache und nicht mehr über eine Map, und natürlich musste ich von Klassen auf Interfaces umstellen, aber ansonsten musste ich im restlichen Code nichts ändern.
 

Joreyk

Mitglied
eine tabelle kannst du immer als record darstellen

was du hast ist das

Java:
record Connections(String configName, String password, String string1, String string2 ...)
das kannst du über ORM mappen, dann kannst du eine factory dazu machen (vllt kann das dein orm mapper auch) die dir diese records umwandelt auf basis der confignamen

dann brauchst du keine 20 tabellen aber du sparst dir das switchen und parsen
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Methodenaufrufe abstrakte Klassen, Interfaces Java Basics - Anfänger-Themen 17
M Wozu dient Interfaces? Java Basics - Anfänger-Themen 6
O Mehrfachvererbung auf Spezifikations- und Implementierungsebene in Java. Interfaces Java Basics - Anfänger-Themen 19
U Funktionale Interfaces mit mehreren abstrakten Methoden? Java Basics - Anfänger-Themen 8
M Interfaces Aufgabe Java Basics - Anfänger-Themen 2
I JSON / XML Struktur mit Vererbung / Interfaces Java Basics - Anfänger-Themen 0
I XML und Interfaces aus anderen Projekten Java Basics - Anfänger-Themen 3
8u3631984 Record - Interfaces Java Basics - Anfänger-Themen 4
M Wie kann ich in einem Konstruktor die Methode eines anderen Interfaces mit den jeweiligen Parametern aufrufen? Java Basics - Anfänger-Themen 8
H Sinn von Interfaces Java Basics - Anfänger-Themen 21
B JaxB und Interfaces? Java Basics - Anfänger-Themen 2
M Funktionale Interfaces Java Basics - Anfänger-Themen 3
Kirby.exe Frage zur Verwendung von Interfaces Java Basics - Anfänger-Themen 6
H Frage zu interfaces Java Basics - Anfänger-Themen 1
J Zweck von Interfaces immer noch nicht klar Java Basics - Anfänger-Themen 3
M Klasse erbt von Interfaces Java Basics - Anfänger-Themen 6
T Interfaces in erbenden Klassen Java Basics - Anfänger-Themen 2
T Abstrakte Klasse und Interfaces Java Basics - Anfänger-Themen 12
H Polymorphie Interfaces und statischer Typ Java Basics - Anfänger-Themen 33
T Verständnisfrage zu Interfaces Java Basics - Anfänger-Themen 7
F Exceptions in Interfaces Java Basics - Anfänger-Themen 4
F Interface Warum Interfaces? Java Basics - Anfänger-Themen 5
R interfaces Java Basics - Anfänger-Themen 1
B Interfaces Java Basics - Anfänger-Themen 6
A Vererbung/Interfaces/Generics Java Basics - Anfänger-Themen 12
D Interface Wieso Aufruf aller Methoden eines Interfaces? Java Basics - Anfänger-Themen 11
J Interfaces? Java Basics - Anfänger-Themen 32
M Erstellung Interfaces....totale Anfängerfrage Java Basics - Anfänger-Themen 16
S Erste Schritte Innere Klassen und Interfaces Java Basics - Anfänger-Themen 2
J Wofür dienen Interfaces ? Java Basics - Anfänger-Themen 1
Hijo2006 Frage zu Interfaces Java Basics - Anfänger-Themen 21
Hacer Interfaces implementieren Java Basics - Anfänger-Themen 7
H Implementierung eines Interfaces erweitern Java Basics - Anfänger-Themen 13
L Via Interfaces unterschiedliche Klassen ansprechen Java Basics - Anfänger-Themen 8
A Verwendung von Interfaces Java Basics - Anfänger-Themen 7
J Interfaces Java Basics - Anfänger-Themen 15
D Frage bzgl. Interfaces Java Basics - Anfänger-Themen 10
D Interface Verständnisprobleme von Interfaces Java Basics - Anfänger-Themen 5
D Interface Interfaces und abstrakte Klassen implementieren Java Basics - Anfänger-Themen 4
S Rollen verändern, Interfaces austauschen wie? Java Basics - Anfänger-Themen 10
K Interfaces/Klassen etc. Java Basics - Anfänger-Themen 6
F Implementierung von Interfaces -> Problem mit main Java Basics - Anfänger-Themen 12
S Verständnisproblem bei Interfaces Java Basics - Anfänger-Themen 6
I Interface Verständnisfrage Interfaces (Bsp.: Enumeration) Java Basics - Anfänger-Themen 2
M Frage zu Generics in Klassen, Abstrakten Klassen und Interfaces Java Basics - Anfänger-Themen 5
O Java Interfaces für andere Programmiersprachen zur Verfuegung stellen? Java Basics - Anfänger-Themen 2
K Interface Generics, Interfaces und Listen - ich bin verwirrt. Java Basics - Anfänger-Themen 7
G Instanzen eines Interfaces erzeugen Java Basics - Anfänger-Themen 7
M Compiler-Fehler Alle Methoden eines Interfaces Implementiert dennoch Fehler Java Basics - Anfänger-Themen 3
V Interface Interfaces und abstrakte Klassen Java Basics - Anfänger-Themen 3
F Best Practice UML/Planung eines Projektes (Klassen, Interfaces, ...) Java Basics - Anfänger-Themen 0
V Vererbung Vererbung, Interfaces und OOP... Java Basics - Anfänger-Themen 10
C Sinn eines Interfaces? Java Basics - Anfänger-Themen 4
A Interface Poymorphismus bei Interfaces Java Basics - Anfänger-Themen 2
Pentalon Eclipse JUNO keine Vorschläge von Methoden bzw. Interfaces der eigenen Klassen Java Basics - Anfänger-Themen 5
R Mehrere Interfaces(Comparable, ...) Java Basics - Anfänger-Themen 2
J Interfaces Abstrakte Klassen Java Basics - Anfänger-Themen 15
D Interfaces und allgemeingültige Methodenaufrufe Java Basics - Anfänger-Themen 6
H Erste Schritte 2 User Interfaces für eine Anwendung Java Basics - Anfänger-Themen 7
S OOP Wann Proxies und Interfaces? Java Basics - Anfänger-Themen 3
M Interface @Inject mit Interfaces? Java Basics - Anfänger-Themen 2
F Interface Unterschied von Attributen und Methoden bei abstrakten Klassen und Interfaces Java Basics - Anfänger-Themen 5
V mehrfachvererbung unter interfaces Java Basics - Anfänger-Themen 10
J Interface Wie funktioniert das mit den Interfaces. Ich verstehe es einfach nicht! :( Java Basics - Anfänger-Themen 15
T Interfaces und Implementierungen Java Basics - Anfänger-Themen 12
S Interface mehrere Interfaces Java Basics - Anfänger-Themen 2
M Vererbung Problem bei Interfaces Java Basics - Anfänger-Themen 8
H Dynamische Bindung mit Interfaces und LinkedList Java Basics - Anfänger-Themen 7
F Interfaces Java Basics - Anfänger-Themen 4
M Frage zu Interfaces Java Basics - Anfänger-Themen 3
N Generics und Interfaces Java Basics - Anfänger-Themen 5
D Abstrakte Klassen und Interfaces als Paramter in Funktionen Java Basics - Anfänger-Themen 3
P OOP Aufruf eines Interfaces Java Basics - Anfänger-Themen 4
N OOP Vererbung von Interfaces Java Basics - Anfänger-Themen 12
S Verständnisfrage zu Interfaces Java Basics - Anfänger-Themen 2
D Sinn von Interfaces - Wozu? Java Basics - Anfänger-Themen 9
P Frage zu Interfaces Bsp. Java Basics - Anfänger-Themen 9
A Deklarationen in abstrakten Klassen und Interfaces Java Basics - Anfänger-Themen 11
R Adapterklassen vs Interfaces Java Basics - Anfänger-Themen 6
P Interfaces -> eins oder mehrere für eine Anwendung? Java Basics - Anfänger-Themen 9
2 Interfaces, Polymorphie und Methoden. Java Basics - Anfänger-Themen 14
A Obstlager Interfaces Java Basics - Anfänger-Themen 7
K Theor. Frage zu Interfaces Java Basics - Anfänger-Themen 30
T Frage zu Interfaces und Abstrakten Klassen Java Basics - Anfänger-Themen 4
J Interfaces Java Basics - Anfänger-Themen 14
L Interfaces Java Basics - Anfänger-Themen 5
J spiel "Gefangenendilemma" Probleme mit Interfaces Java Basics - Anfänger-Themen 8
H Interfaces in java? Java Basics - Anfänger-Themen 2
A OOP Interfaces mit gleichem Methoden Java Basics - Anfänger-Themen 15
T Interfaces: Braucht man abstrakte Klassen eigentlich noch? Java Basics - Anfänger-Themen 3
S Implementierung gegen Interfaces / List, ArrayList, LinkedList Java Basics - Anfänger-Themen 11
D Interfaces / Schnittstellen Java Basics - Anfänger-Themen 8
I Probleme mit Interfaces Java Basics - Anfänger-Themen 4
K Interfaces "Schreibaufwand" Java Basics - Anfänger-Themen 53
I Interfaces Java Basics - Anfänger-Themen 34
bigbasti Warum genau braucht man Interfaces? Java Basics - Anfänger-Themen 10
A Programmieren gegen Interfaces Java Basics - Anfänger-Themen 4
I Frage zu Collection und List Interfaces Java Basics - Anfänger-Themen 2
7 Interfaces - Aufbau Java Basics - Anfänger-Themen 9
G Interfaces mit gleichen Methoden Java Basics - Anfänger-Themen 4

Ähnliche Java Themen


Oben