Zum Inhalt springen
  • 0

Wann beziehe ich mich auf Interfaces?


Frage

Geschrieben

Hallo Leute!

Mir fällt es schwer zu verstehen wann ich mich auf Interfaces statt auf konkrete Klassen beziehen sollte.

Nehmen wir an ich möchte eine Benutzer Registrierung für einen Login schreiben.

Ich habe ein Klasse für die View, eine Klasse für den Benutzer und eine Klasse die den neuen Benutzer verschlüsselt speichert. Ich verstehe nicht ganz ob hier ein Interface sinnvoll wäre oder nicht.

Wenn ich in der Klasse view daten zum Benutzer runtergebe und ich die verschlüsselung der speicherKlasse mittels static übergebe, hab ich nur eine Kopplung von der view zum Benutzer.

Is das nicht i.O?

Klärt mich auf xD LG!

 

 

 

4 Antworten auf diese Frage

Empfohlene Beiträge

  • 1
Geschrieben (bearbeitet)

In deinem Fall könnte es für Hashen eines Passworts interessant sein, damit könntest du den Algorithmus konfigurierbar gestalten.

interface Hash {
	public string hash(string password);
}

class MD5 implements Hash {
   public string hash(string password) {
	  // md5 in der realität bitte nicht mehr verwenden
   	  return md5(password);
   }
}


class bcrypt implements Hash {
	public string hash(string password) {
		return bcrypt(password);
	}
}


// Nun kannst du deinen User so gestatlten das deine Verschüsselung konfigurierbar ist in dem du die Klasse über den Konstruktor überigbst.
// Das nennt sich dann "Dependency Injection" oder auf deutsch "Abhängigkeitseinführung" - also Abhängigkeiten auf einer anderen Klasse
// über eine Methode in die Klasse reinzureichen.
// In größeren Projekten gibt es Methoden dies zu automatisieren und zu konfigurieren, aber hier uninteressant.

class User {
    private Hash hash;

    public User(hash Hash) {
   		this.hash = hash;
    }

    public void setHash(Hash hash) {
    	this.hash = hash;
    }

    public void register(user string, password string) {
    	hashedPass = this.hash(password);
		// speicher mit gehashtem Passwort
        save(user, hashedPass)
	}
}



// hier mal der Aufruf

Hash md5Hash = new MD5();
User user = new User(md5Hash);
user.save("max mustermann", "12345password");

// Nun kannst du den Hashalgorhytmus auch zur Laufzeit ändern über die "setHash"-Methode
Hash bcrypt = new bcrypt();
user.setHash(bcrypt);
// Nun wird der neue Hashalgorhytmus verwendet
user.save("sabine mustermann", "12345pass");

 

In größeren Projekten wird dieses vorgehen genutzt um deine Applikation zu konfigurieren. Du könntest nun eine Konfig-Datei auslesen in der ein Parameter z.B. "passwort-hash-algorithm: bcrypt" gesetzt wird um es Konfiguriertbarer zu machen.

In der Implementierung ist es dann natürlich notwendig das du dir Gedanken machst wie deine Datenstrukturen aussehen, bei einem einfachen string ist es noch einfach. Wenn du wie in deinem Fall Datenstrukturen eins zu eins unverändert weiterreichst hast du dann tatsächlich auch eine direkte Abhängigkeit auf von der Verschlüsselung auf deine View - obwohl du ja technisch theoretisch unabhängig bist. 

Am Anfang ist das Thema schwer zu verstehen da die Projekte noch nicht groß genug sind um die Benefits zu sehen. Das du die Methoden statisch aufrufst ist kein Problem sondern in dem Fall sogar die einfachste und damit auch eine gute Lösung.
Die hier beschriebenen Methoden machen deine Arbeit deutlich aufwendiger und sind in kleinen Projekten noch nicht notwendig, daher ist es etwas Frustig sich in die Themen einzuarbeiten.

Wenn dich das Thema genauer interessiert gibt es dazu ein "Design-Pattern" welches sich "Strategy"-Pattern schimpft, da könnten die Anwendungsfälle interessanter für dich werden.
https://www.youtube.com/watch?v=-NCgRD9-C6o

Wenn du noch deutlich mehr über OOP in der Anwendung erfahren möchtest empfehle ich dir das Buch "Entwurfsmuster von Kopf bis Fuß", es ist auf deutsch und sehr angenehm geschrieben. Das Buch war für mich der Klickpunkt in der OOP-Programmierung.

https://www.amazon.de/Entwurfsmuster-von-Kopf-bis-Fu%C3%9F/dp/3955619869

OOP-Konzepte gehen noch viel weiter und sind nach dem Buch auf keinen Fall beendet, an dieser Stelle wären sie allerdings fehl am Platz :)

Ich hoffe dir konnte mein Input etwas helfen.

Bearbeitet von _Sly
  • 0
Geschrieben

@_Sly Gute Antwort. Allerdings Beispielcode, der mit ziemlicher Sicherheit auf 'ne Exception hinausläuft. ?

Grundsätzlich machen Interfaces in größeren Applikationen Sinn, sehe ich ähnlich. Bezogen auf das konkrete Beispiel würde ich mich fragen ob das nicht etwas Overkill ist. Du wirst Passwörter ja eigentlich nicht unterschiedlich verschlüsseln, sondern dich auf eine Methode festlegen. Weil du ansonsten unnötige Komplexität zum Login hinzufügst, da du bei jedem Login auf irgendeine Weise prüfen müsstest welche Hashing-Funktion genutzt wurde.

Das Interface würde hier also eher den ursprünglichen Zweck erfüllen, Vorgaben für deine Klasse User zu machen und kann dir gleichzeitig eine Hilfestellung sein, da du in einer modernen IDE einen Fehler angezeigt bekommst, solange das Interface nicht vollständig implementiert ist. Das führt mitunter dazu, dass Leute sauberer arbeiten, auch wenn es natürlich ein beträchtlicher Mehraufwand sein kann.

  • 0
Geschrieben

Schau dir eventuell mal die SOLID Prinzipien (vor allem die Papers von Uncle Bob) an. Generell ist es auf längere Sicht und bei größeren Projekten sinnvoll gegen Abstraktionen zu programmieren.

Hier mal noch ein generelles (einfaches) Beispiel:

Du hast 3 Klassen: Kreis, Rechteck, Dreieck. Deine Aufgabe ist es eine App zu entwickeln, welche den Flächeninhalt berechnet. Das neue geometrische Formen unterstützt werden müssen, ist nicht ausgeschlossen. Wie würdest du vorgehen? 

Hier mal meine Vorgehensweise mit Bezug auf Interfaces

interface IFlaecheninhalt 
{
	getFlaecheninhalt();
}

class Kreis implements IFlaecheninhalt 
{ 
	getFlaecheninhalt 
    {
    	return ...
    }
}

class Rechteck implements IFlaecheninhalt 
{ 
	getFlaecheninhalt 
    {
    	return ...
    }
}

class Dreieck implements IFlaecheninhalt 
{ 
	getFlaecheninhalt 
    {
    	return ...
    }
}
/*------------------------------------------------------------------------*/
// So könntest du jetzt eine App umsetzen

IFlaecheninhalt[] geometrischeObjekte;
geometrischeObjekte[0] = Rechteck;
geometrischeObjekte[1] = Dreieck;
geometrischeObjekte[2] = Kreis;

function app(IFlaecheninhalt[] geometrischeObjekte) 
{
	for(IFlaecheninhalt objekt : geometrischeObjekte) {
		flaeche = geometrischesObjekt.getFlaecheninhalt();
        flaeche auf Konsole ausgeben
    }
}


Was hat dir das gebracht? Zum einen beziehst du dich in deiner app Funktion nur auf die Abstraktion "IFlaecheninhalt". WIE aber die Funktion getFlaecheninhalt implementiert ist, sollte dir komplett egal sein. Möchte dein Auftraggeber später nun bspw. noch Vierecke dazu nehmen, musst du nur eine Klasse Viereck erstellen und diese das Interface IFlaecheninhalt implementieren lassen. Deine app Funktion ändert sich nicht. Zum erweitern deiner App schreibst du also eher neuen Code, als bestehenden Code anzupassen bzw. abzuändern.

**Man kann sowas natürlich auf X beliebige Arten lösen. 

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Diese Frage beantworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...