Wie ist der Begriff "Interface" hier zu verstehen?

Peter_2498

Lieutenant
Registriert
Apr. 2018
Beiträge
555
Hallo zusammen,

ich lese gerade ein Buch über Software Design, wo es gerade um modulare Programmierung geht. Es wird geschrieben: "we think of each module in two parts: an interface and an implementation".

Im Internet habe ich folgendes gelesen, was wohl in die Richtung des Buches geht: "In general, we say that the interface to a module defines how other modules can use that module."

Ich habe noch absolut keine professionelle Erfahrung mit Programmierung und deswegen verstehe ich nicht so ganz was hier mit "Interface" gemeint ist? Meint man das Interface aus Java bzw. sowas wie die "pure virtual functions" aus C++?
 
An interface defines the signature operations of an entity, it also sets the communication boundary between two entities, in this case two pieces of software. It generally refers to an abstraction that an asset provides of itself to the outside.
Ich glaub das ist aber auch sehr kontextabhängig. Beim ersten Lesen von "Interface" in Verbindung mit Software bzw. Programmierung kommt mir API/Schnittstelle in den Sinn.
 
  • Gefällt mir
Reaktionen: GTrash81
Um es nochmal klar zu stellen:
Damit ist nicht generell das Sprachkonstrukt des Interfaces aus Java gemeint. Ein solches Modul-Interface kann zwar durchaus über ein oder mehrere Java-Interfaces realisiert werden. Dennoch ist die Bedeutung hier eine andere.

Interfaces (also APIs) sind älter als die Objektorientierte Programmierung. Ein Modul-Interface ist eher als die Summe der öffentlich zugänglichen Funktionen zu verstehen (öffentlich kann hier auch nur bedeuten: von außerhalb des Moduls). Und das kann auf verschiedene Wege umgesetzt werden. API ist also ein sehr allgemeiner und eher abstrakter Begriff. Ein Web-Server kann auch eine öffentliche API über HTTP anbieten.
 
  • Gefällt mir
Reaktionen: BeBur, mental.dIseASe und Peter_2498
Das Interface beschreibt was du an einem Objekt aufrufen kannst und was diese Schnittstellen tun bzw. zurückgeben. Die Implementation beschreibt dann wie diese Operation konkret gelöst wird.
 
  • Gefällt mir
Reaktionen: jlnprssnr und floTTes
@Drarlor: Und dennoch kann ein Objekt kein Klassen-Interface haben (implementieren) und dennoch hat es auch eine API.
Auch wenn sich das Konzept ähnlich anhört in Bezug auf Schnittstelle und Implementierung, weil man es bei Klassen und Interfaces ja ähnlich kennt, haben APIs und Klassen-Interfaces dennoch wenig miteinander zu tun.

Wenn du allerdings "Objekt" weglässt und es durch Modul ersetzt, habe ich wenig auszusetzen (außer dass ich vielleicht nicht "beschreibt" verwendet hätte bei der Implementierung).
 
  • Gefällt mir
Reaktionen: Peter_2498
Danke erstmal für die ganzen Erklärungen. Das scheint wohl ein sehr allgemeiner Begriff zu sein. Ich muss vorerst meine Gedanken ordnen.

1.Kann man sagen, dass die public Variablen und Methoden einer Klasse eine Art (triviale) API darstellen? Ich habe ja dadurch eine Schnittstelle für mein Objekt, worauf andere zugreifen können?

2.Eine stinknormale Funktion, die ich benutze, hat doch dann ebenfalls eine triviale API (Eingabevariablen)?
 
1, Ja, wie ich sagte, ein Objekt hat auch ohne explizit ein Interface zu implementieren eine API in der Form seiner öffentlichen Methoden und Variablen.

2. Kann man überspitzt wohl so formuliren, hängt aber auch sicher von der Funktion ab und was sie tut. Übernimmt eine Funktion genau eine einzige Aufgabe (z.B. mathematische Funktionen für Summe, Minimal-/Maximalwert ermitteln, Wurzeln, trigonometrische Funktion etc.) würde ich das wohl nicht so sagen. Aber nimmt man z.B. so etwas wie einen Formatierer (z.B. für Datumswerte), dann kann man das schon so sehen.
 
Alles klar, jetzt wird mir das schon klarer.

Was wären denn andere einfache APIs?
 
tollertyp schrieb:
Was verstehst du unter einfache APIs?
Einfach nur weitere nicht so komplizierte Möglichkeiten für APIs, damit ich ein besseres Gefühl dafür bekomme, wie so eine API denn aussehen/implementiert sein kann.
 
Beispiele:
  1. Austausch von Fluginformationen zwischen Fluggesellschaften und Reise-Webseiten
  2. Google Maps in einer Mitfahr-App verwenden
  3. Aufbau von Chatbots in einem Messaging-Service
  4. Einbetten von YouTube-Videos in eine Webseite
  5. Automatisierung von Arbeitsabläufen zwischen B2B-Software-Tools
Das 3. und 4. erklärt es imho ganz gut.
 
Es geht mir um die Implementation. Eine nicht ganz so komplexe API, die über meine trivialen Beispiele hinaus geht. Einfach dass ich sehe, wie das als Code realisiert wurde.
 
Nach dem, was du in deinem ersten Beitrag aus dem Buch zitiert hast, gehe ich recht stark davon aus, dass von etwas die Rede ist, was dem, was Java unter Interface versteht, schon recht nahe kommt.

Du hast um ein konkretes aber einfaches Beispiel gebeten. Hier zuerst die Klassen dazu:

Java:
public interface Logger {
    
    void log(String message);
}

Java:
public class ConsoleLogger implements Logger {
    
    public void log(String message) {
        System.out.println(message);
    }
}

Java:
public class FileLogger implements Logger {
    
    private final BufferedWriter writer;
    
    
    
    public FileLogger(File file) throws FileNotFoundException {
        writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));
    }
    
    
    
    public void log(String message) {
        
        try {
            writer.write(message);
            writer.newLine();
            writer.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

Java:
public class Example {
    
    public static void main(String[] args) throws FileNotFoundException {
        
        Logger logger = new FileLogger(new File("./log.txt"));
        logger.log("Hello World!");
    
        logger = new ConsoleLogger();
        logger.log("Hello World the second!");
    }
    
}

In fast jedem Programm, das eine gewisse Komplexität erreicht hat, wird es eine Form von Protokollierung geben, auch genannt Logging. Protokolliert kann auf viele verschiedene Weisen werden, zum Beispiel direkt in die Konsole bei Kommandozeilenprogrammen, in eine Datei, in ein Fenster auf den Bildschirm, in eine Datenbank und so weiter und so fort.

Dem Programm, welches dieses Protokoll schreiben möchte, ist herzlich egal, wie das alles im Hintergrund funktioniert. Es will einfach nur wissen, ob eine bestimmte Klasse die Funktionalität eines Logger bereitstellt, damit es diese als solche benutzen kann. Die Klassen ConsoleLogger und FileLogger geben an, diese Funktionalität bereit zu stellen, indem sie dieses Interface implimentieren.

Ich hoffe, das hilft dir ein wenig weiter.
 
  • Gefällt mir
Reaktionen: Peter_2498
@Killkrog
Ich versuche mir gerade klar zu machen, wie ich das in Einklang bringe mit dem Konzept, dass Interfaces möglichst viel Komplextität eines Moduls "verstecken" sollten oder möglichst simpel sein sollten.

Bei Interfaces oder APIs von Objekten oder Funktionen ist vollkommen klar, was man damit erreichen will. Man möchte z.B. nicht, dass jemand bei einer Funktion zig komplizierte Parameter angeben muss, die man im Normalfall zu 99% nicht braucht oder so ähnlich. Hier ist auch Interface und Implementation klar, beides als Teil der Funktion bzw. des Objekts/der Klasse.

Wenn wir jetzt allerdings zum Interface als Programmierkonstrukt wie in Java schauen, dann sieht das für mich nach einer etwas abstrakteren Methode aus, eine Art Interface für ein ganzes Modul zu kreieren. Ich will mich jetzt bezüglich deines Beispiels in die Perspektive des Programmierers versetzen, der das Programm fürs Protokoll schreibt und dafür einen Logger braucht. Und er sieht direkt: "Aha, wir haben hier also ein Logger Interface, welches mir alle benötigten Funktionen bereitstellt, die ich benötige. Da ConsoleLogger und FileLogger das implementiert haben, brauche ich mir die beiden anderen Klassen überhaupt nicht mehr genauer anzusehen, da sie diese Funktionalität besitzen müssen". In dem Sinne sehe ich dieses Programmierkonstrukt "Interface" als ein abstrakteres Interface in dem Sinne, dass es mir schnell zeigt, was ich in dem jeweiligen Modul mehr oder weniger von der Funktionalität zu erwarten habe, ohne dass ich die ganzen mögliche Klassen des Moduls nach den Funktionalitäten durchsuchen muss. Damit ist das ebenfalls eine gute Methode Implementation zu "verstecken", wenn jemand das Modul nur "nutzt".
Kann man das alles ungefähr so sehen?
 
Dass eine API die Implementierung "versteckt" ist halt ein Nebeneffekt und nicht zwingend das Ziel. Spätestens wenn man Anwendungen debuggt ist man froh, dass die Implementierung nur selten wirklich versteckt wird. Wobei auch die Frage ist wie das Verstecken gemeint ist - im Sinne der Geheimhaltung oder im Sinne von "Lass bitte die Finger davon, das ist nur für die interne Verwendung".

Das Ziel einer API ist es halt, eine Funktionalität anzubieten. Wenn man es überspitzt, dann sogar nur zu beschreiben, weil letztendlich ja die Implementierung die Funktionalität letztenendes anbietet. Insofern versteckt die API eigentlich nicht wirklich etwas, es ist der Nebeneffekt.
 
Peter_2498 schrieb:
Ich versuche mir gerade klar zu machen, wie ich das in Einklang bringe mit dem Konzept, dass Interfaces möglichst viel Komplextität eines Moduls "verstecken" sollten oder möglichst simpel sein sollten.
Nun, noch minimalistischer als das hier geht es ja fast nicht.
Java:
public interface Logger {
    void log(String message);
}

Peter_2498 schrieb:
Man möchte z.B. nicht, dass jemand bei einer Funktion zig komplizierte Parameter angeben muss, die man im Normalfall zu 99% nicht braucht oder so ähnlich.
Das ist meiner Meinung nach nicht Aufgabe eines Interfaces. Da gibt es andere, deutlich besser geeignete Methoden. Du kannst dir zum Beispiel das Builder Pattern oder überladene Funktionen ansehen.

Peter_2498 schrieb:
Wenn wir jetzt allerdings zum Interface als Programmierkonstrukt wie in Java schauen, dann sieht das für mich nach einer etwas abstrakteren Methode aus, eine Art Interface für ein ganzes Modul zu kreieren. Ich will mich jetzt bezüglich deines Beispiels in die Perspektive des Programmierers versetzen, der das Programm fürs Protokoll schreibt und dafür einen Logger braucht. Und er sieht direkt: "Aha, wir haben hier also ein Logger Interface, welches mir alle benötigten Funktionen bereitstellt, die ich benötige. Da ConsoleLogger und FileLogger das implementiert haben, brauche ich mir die beiden anderen Klassen überhaupt nicht mehr genauer anzusehen, da sie diese Funktionalität besitzen müssen". In dem Sinne sehe ich dieses Programmierkonstrukt "Interface" als ein abstrakteres Interface in dem Sinne, dass es mir schnell zeigt, was ich in dem jeweiligen Modul mehr oder weniger von der Funktionalität zu erwarten habe, ohne dass ich die ganzen mögliche Klassen des Moduls nach den Funktionalitäten durchsuchen muss. Damit ist das ebenfalls eine gute Methode Implementation zu "verstecken", wenn jemand das Modul nur "nutzt".
Kann man das alles ungefähr so sehen?
Ich glaube, du hängst dich ein wenig zu sehr an dem Verstecken auf. Ein Interface verbirgt zwar definitiv das Innenleben der Implementierung, aber das ist meiner Meinung nicht die Aufgabe eines Interfaces.

Die Aufgabe eines Interface ist wirklich nur die Definition von Aufgaben und Fähigkeiten.

Stell dir vor, du arbeitest in einer Software-Schmiede. Dein Product-Analyst kommt zu dir und sagt: "Hey, Peter, unsere Kundschaft hätte gerne die Möglichkeit, unsere Produkte anstatt in dem bereits existierenden Katalog auch über eine filterbare Suche finden zu können. Kümmerst du dich da drum?"

Du, als erfahrener Entwickler weißt natürlich, das wird wieder mal eine etwas größere Operation, also setzt du dich mit deinem UX Team zusammen. Mit dem tüfteltst du jetzt aus, wie genau das Ganze am Ende in eurem UI aussehen soll.

Da du in einem Team arbeitest, was einigermaßen Ahnung hat von dem, was es tut, habt ihr in der Vergangenheit darauf geachtet, euer Frontend (Benutzeroberfläche) und euer Backend (Geschäftslogik) voneinander zu trennen. Also packst du dir den Programmierer aus deinem Team, von dem du weißt, dass er sich gut mit dem Frontend auskennt, weil du selbst eher der Backend Mensch bist.

Ihr macht euch also einen Kaffee und denkt drüber nach, was das UI braucht, um ordentlich funktionieren zu können und schreibt zusammen ein Interface, welches definiert, was das Backend liefern muss.

Dein Frontend Programmierer und du selbst seid glücklich, weil ihr mit dem Arbeiten anfangen könnt. Er weiß, was du liefern wirst und es ist ihm komplett egal, wie du das anstellst. Du weißt, was du liefern musst.

Dies war ein Beispiel, wann ein Interface innerhalb eines Projektes benutzt wird. Genauso kann es natürlich auch benutzt werden, um Endbenutzern Funktionalität anzubieten. Das kann man hier zum Beispiel sehr gut sehen: https://esi.evetech.net
 
  • Gefällt mir
Reaktionen: Peter_2498, jlnprssnr und KitKat::new()
Zurück
Oben