Dependecy Injektion

Mariexshhx

Bekanntes Mitglied
private void sendMail(Kunde kunde) {
Mail mail = createMail(kunde.getName());
ProcessBuilder processBuilder = new ProcessBuilder();
Process process = null;
try {
process = processBuilder
.command("java", "-jar", Paths.get("lib", "ext", "mail.jar").toString(), kunde.getEmail(),
mail.getSubject(),
mail.getBody())
.redirectOutput(INHERIT)
.redirectError(INHERIT)
.start();
process.waitFor(5, SECONDS);

} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}

ist hier mit Dependecy Injektion gemeint, dass man ein ProcessBuilder Objekt übergeben soll, anstatt es in der Methode zu erzeugen?
 
Y

yfons123

Gast
das ist so ziemlich das beispiel das am wenigsten mit dependency injection zu tun hat wie es nur irgendwie möglich ist
 

Mariexshhx

Bekanntes Mitglied
private Mail granita(String name) {
String subject = "Frühstücken wie in Sizilien?";
String body = String.format("Hallo %s,%n%n" +
"Wenn es in Sizilien warm ist, dann frühstücken wir ein Granita al limone. Ein fruchtiges Zitronensorbet und dazu gibt es ein Brioche und Espresso.%n%n" +
"%n%nKomm vorbei und starte den Tag wie im Urlaub.%n%n" +
"Wir freuen uns auf Dich!%nDein Team von Gelateria Giacomo%n", name);
body += covid();
return new Mail(subject, body);
}

oder hier sollte dann das return new Mail verhindert werden ?
 

httpdigest

Top Contributor
Kontext!!! Wovon redest du überhaupt? Wieso kommst du hierdrauf? Was ist das für ein Code? Wo kommt der her? Wieso glaubst du, dass das was mit Dependency Injection zu tun haben könnte?
 

Mariexshhx

Bekanntes Mitglied
ich habe mehrere Klassen gegegeben, bei denen ich die Aufgabe habe Dependecy Injection anzuwenden
 

Anhänge

  • Marketing.java
    9,1 KB · Aufrufe: 5

Mariexshhx

Bekanntes Mitglied
Kontext!!! Wovon redest du überhaupt? Wieso kommst du hierdrauf? Was ist das für ein Code? Wo kommt der her? Wieso glaubst du, dass das was mit Dependency Injection zu tun haben könnte?
es geht um eine Eisdiele die Abhängig vom Wetter und Abhängig vom Tag Emails an Kunden in einer Datenbank schickt ich soll das das Programm besser strukturieren
 

Robert Zenz

Top Contributor
Nein nein nein nein...bei Dependency Injection geht es darum die Abhaengigkeiten von Aussen der Logik zuzufuehren um zu verhindern dass sich die Logik darum kuemmern muss.

Greifen wir mal schnell ein Beispiel aus der Lust. Wir wollen eine E-Mail versenden.

Java:
public void sendEMail() {
    EMail email = new Email()
            .withSender("myaddress@gmail.com")
            .withReceiver("someone@else.com")
            .withSubject("Test")
            .withText("That Lorem Ipsum Stuff");
   
    EMailProvider provider = new EMailProvider()
            .withServer("something.gmail.com")
            .withUsername("myaddress@gmail.com")
            .withPassword("123456");
    
    provider.sendEMail(email);
}

So, wie wir sehen versenden wir hier eine E-Mail, jetzt ist aber das Problem dass *alles* in dieser einen Funktion ist. Also wenn wir die EMail ueber einen anderen Dienst versenden wollen, oder vielleicht auch nur in eine lokale Warteschlange einreihen wollen, muessen wir diese Funktion aendern. Das ist doof. Deswegen reicht man die Abhaengigkeiten einfach in die Funktion:

Java:
public void sendEMail(EMailProvider provider) {
    EMail email = new Email()
            .withSender("myaddress@gmail.com")
            .withReceiver("someone@else.com")
            .withSubject("Test")
            .withText("That Lorem Ipsum Stuff");
   
    provider.sendEMail(email);
}

Oder als Feld bei der Uebergabe im Kosntruktor:

Java:
private EMailProvider provider;

public EMailSender(EMailProvider provider) {
    this.provider = provider;
}

public void sendEMail() {
    EMail email = new Email()
            .withSender("myaddress@gmail.com")
            .withReceiver("someone@else.com")
            .withSubject("Test")
            .withText("That Lorem Ipsum Stuff");
   
    provider.sendEMail(email);
}

Oder wenn man auf Spring und Felder steht (was man dann nicht mehr so einfach testen kann weil man im Test sich schwer tut das Feld auszutauschen):

Java:
@Injected
private EMailProvider provider;

public void sendEMail() {
    EMail email = new Email()
            .withSender("myaddress@gmail.com")
            .withReceiver("someone@else.com")
            .withSubject("Test")
            .withText("That Lorem Ipsum Stuff");
   
    provider.sendEMail(email);
}

So oder so, die Abhaengigkeit wird der Logik uebergeben. Damit koennen wir die Funktion von aussen wiederverwenden ohne sie aendern zu muessen. Desweiteren koennen wir dann in unseren Tests ganz einfach einen Test-EMailProvider an die Funktion uebergeben und muessen nicht jedes mal echte EMails versenden.

So, noch ein wichtiger Nachsatz den viele nicht begreifen: Nur weil man Dependency Injection einsetzt heiszt es nicht dass man ploetzlich keinen Monolithen von einem Programm mehr hat. Man hat sehr wohl einen Monolithen, aber jetzt haengen die einzelnen Teile alle zusammen mit Faeden die man nicht mehr sieht.
 

Mariexshhx

Bekanntes Mitglied
Nein nein nein nein...bei Dependency Injection geht es darum die Abhaengigkeiten von Aussen der Logik zuzufuehren um zu verhindern dass sich die Logik darum kuemmern muss.

Greifen wir mal schnell ein Beispiel aus der Lust. Wir wollen eine E-Mail versenden.

Java:
public void sendEMail() {
    EMail email = new Email()
            .withSender("myaddress@gmail.com")
            .withReceiver("someone@else.com")
            .withSubject("Test")
            .withText("That Lorem Ipsum Stuff");
  
    EMailProvider provider = new EMailProvider()
            .withServer("something.gmail.com")
            .withUsername("myaddress@gmail.com")
            .withPassword("123456");
   
    provider.sendEMail(email);
}

So, wie wir sehen versenden wir hier eine E-Mail, jetzt ist aber das Problem dass *alles* in dieser einen Funktion ist. Also wenn wir die EMail ueber einen anderen Dienst versenden wollen, oder vielleicht auch nur in eine lokale Warteschlange einreihen wollen, muessen wir diese Funktion aendern. Das ist doof. Deswegen reicht man die Abhaengigkeiten einfach in die Funktion:

Java:
public void sendEMail(EMailProvider provider) {
    EMail email = new Email()
            .withSender("myaddress@gmail.com")
            .withReceiver("someone@else.com")
            .withSubject("Test")
            .withText("That Lorem Ipsum Stuff");
  
    provider.sendEMail(email);
}

Oder als Feld bei der Uebergabe im Kosntruktor:

Java:
private EMailProvider provider;

public EMailSender(EMailProvider provider) {
    this.provider = provider;
}

public void sendEMail() {
    EMail email = new Email()
            .withSender("myaddress@gmail.com")
            .withReceiver("someone@else.com")
            .withSubject("Test")
            .withText("That Lorem Ipsum Stuff");
  
    provider.sendEMail(email);
}

Oder wenn man auf Spring und Felder steht (was man dann nicht mehr so einfach testen kann weil man im Test sich schwer tut das Feld auszutauschen):

Java:
@Injected
private EMailProvider provider;

public void sendEMail() {
    EMail email = new Email()
            .withSender("myaddress@gmail.com")
            .withReceiver("someone@else.com")
            .withSubject("Test")
            .withText("That Lorem Ipsum Stuff");
  
    provider.sendEMail(email);
}

So oder so, die Abhaengigkeit wird der Logik uebergeben. Damit koennen wir die Funktion von aussen wiederverwenden ohne sie aendern zu muessen. Desweiteren koennen wir dann in unseren Tests ganz einfach einen Test-EMailProvider an die Funktion uebergeben und muessen nicht jedes mal echte EMails versenden.

So, noch ein wichtiger Nachsatz den viele nicht begreifen: Nur weil man Dependency Injection einsetzt heiszt es nicht dass man ploetzlich keinen Monolithen von einem Programm mehr hat. Man hat sehr wohl einen Monolithen, aber jetzt haengen die einzelnen Teile alle zusammen mit Faeden die man nicht mehr sieht.
ah danke, ich verstehe, dass man dann das provider Objekt der Methode übergibt anstatt es in der Methode zu erstellen. ich bin mir nur unsicher wie ich bei meinem Beispiel vorgehen soll
 

Mariexshhx

Bekanntes Mitglied
  • <Definieren Sie die Schnittstellen der Komponenten und kapseln Sie jede Komponente in einem Java-Package.
  • Sorgen Sie für die Trennung von Konstruktion und Ausführung durch Verwendung von Dependency Injection.
  • Verwenden Sie Dependency Inversion, um die Kopplung zwischen den Komponenten zu lockern.
 

Robert Zenz

Top Contributor
Ist 'ne tolle Uebung wenn es ums aufraeumen und umbauen geht...

Also du willst eigene Klassen fuer:

1. Den Zugriff auf die Datenbank.
2. Das senden der Email.
3. Vielleicht noch das erstellen von Emails.

Diese uebergibst du am besten der Klasse im Konstruktor.

Also das Ziel ist dass die Marketing Klasse nicht weisz was eine Email ist, wie genau diese versendet wird und auch nicht in welche Datenbank geschrieben wird. Von diesen Sachen sollte die Logik losgeloest sein in dem man sie in eigene Klassen kapselt und diese dann nur noch aufruft.
 

Mariexshhx

Bekanntes Mitglied
dass sind dann doch quasi meine Schnittstellen oder ?
Ist 'ne tolle Uebung wenn es ums aufraeumen und umbauen geht...

Also du willst eigene Klassen fuer:

1. Den Zugriff auf die Datenbank.
2. Das senden der Email.
3. Vielleicht noch das erstellen von Emails.

Diese uebergibst du am besten der Klasse im Konstruktor.

Also das Ziel ist dass die Marketing Klasse nicht weisz was eine Email ist, wie genau diese versendet wird und auch nicht in welche Datenbank geschrieben wird. Von diesen Sachen sollte die Logik losgeloest sein in dem man sie in eigene Klassen kapselt und diese dann nur noch aufruft.
 

Mariexshhx

Bekanntes Mitglied
In der Aufgabe steht halt, dass man in Zukunft eine andere datenbank einen anderen Wetterdient und einen eigenen Mailserver verwenden will
 

Robert Zenz

Top Contributor
Definieren Sie die Schnittstellen der Komponenten und kapseln Sie jede Komponente in einem Java-Package.
Auslegungssache, muesste man wissen was genau gefordert ist. Ich sehe bei der Uebung keinen Sinn dahinter sich Schnittstellen und dann Implementierungen anzulegen. Wenn du die einmal sauber in Klassen aufgeteilt hast, spielt das naemlich keine unmittelbare Rolle weil du ja das Prinzip verstanden hast wie man die Sachen trennen muss.

Desweiteren bin ich absolut kein Freund von dem Vorgehen dass man sich einfach mal einen Haufen Schnittstellen anlegt und dann die *einzige* Implementierung direkt daneben packt:

Java:
public interface EMailProvider {}

public class EMailProviderImpl {}

Ich finde das furchtbar, das riecht so nach "we lots OOP now".

Aber wie gesagt, ich weisz jetzt nicht was genau bei der Aufgabe gefordert ist.

verstehe ich das richtig, dass dann die Methoden create und getKunden dann in die eine eigene Klasse Datenbank gehören. Wobei ich mir bei getKunden nicht sicher bin. Es ist aber auch eine Datenbank Abfrage
Ja.
 

Mariexshhx

Bekanntes Mitglied
es ist halt schon eine Klasse Mail vorgegeben die ja keinen spezifischen Mail anbieter vorgibt deswegen bin ich etwas verwirrt
Auslegungssache, muesste man wissen was genau gefordert ist. Ich sehe bei der Uebung keinen Sinn dahinter sich Schnittstellen und dann Implementierungen anzulegen. Wenn du die einmal sauber in Klassen aufgeteilt hast, spielt das naemlich keine unmittelbare Rolle weil du ja das Prinzip verstanden hast wie man die Sachen trennen muss.

Desweiteren bin ich absolut kein Freund von dem Vorgehen dass man sich einfach mal einen Haufen Schnittstellen anlegt und dann die *einzige* Implementierung direkt daneben packt:

Java:
public interface EMailProvider {}

public class EMailProviderImpl {}

Ich finde das furchtbar, das riecht so nach "we lots OOP now".

Aber wie gesagt, ich weisz jetzt nicht was genau bei der Aufgabe gefordert ist.


Ja.
 

Mariexshhx

Bekanntes Mitglied
  • <Definieren Sie die Schnittstellen der Komponenten und kapseln Sie jede Komponente in einem Java-Package.
  • Sorgen Sie für die Trennung von Konstruktion und Ausführung durch Verwendung von Dependency Injection.
  • Verwenden Sie Dependency Inversion, um die Kopplung zwischen den Komponenten zu lockern.
es sind genau die Sachen gefordert und bei Dependency Inversion geht es doch um Interfaces
 

Mariexshhx

Bekanntes Mitglied
die ganzen Methoden auf die in create Mail in Mail zugegriffen werden sind in der Klasse Marketing und ich habe sie public gemacht. Sie werden aber trotzdem nicht erkannt
 

shokwave

Mitglied
Hi, die Methoden sind zwar public, aber eben in einer anderen Klasse und da sie nicht statisch sind benötigst du ein Objekt der Klasse, um auf sie zuzugreifen.
 

Neumi5694

Top Contributor
die ganzen Methoden auf die in create Mail in Mail zugegriffen werden sind in der Klasse Marketing und ich habe sie public gemacht. Sie werden aber trotzdem nicht erkannt
Du denkst zu viel über Quelltext (Klassen und Methoden) nach und zu wenig darüber, was die Methoden eigentlich aussagen oder bewirken sollen.

Wenn man z.B. ein getName() ansprechen will, dann macht man das ja nicht aus Spaß, sondern will den Namen von JEMANDEM (oder etwas) wissen. Also ist zuerst mal diese Person wichtig, eine ihrer Eigenschaften ist eben der Name.
Mit den anderen Zugriffsmethoden verhält es sich nicht anders.

Immer wieder liest man im Forum. Wie greift man auf die Methoden einer anderen Klasse zu, wo es sich doch um ein anderes Objekt oder eine andere Instanz (egal welcher Klasse) handelt. Würde die Frage so gestellt, dann würde sie selbst beantworten. Man würde das Objekt nennen und danach dessen Methode ansprechen.
 

Mariexshhx

Bekanntes Mitglied
Du denkst zu viel über Quelltext (Klassen und Methoden) nach und zu wenig darüber, was die Methoden eigentlich aussagen oder bewirken sollen.

Wenn man z.B. ein getName() ansprechen will, dann macht man das ja nicht aus Spaß, sondern will den Namen von JEMANDEM (oder etwas) wissen. Also ist zuerst mal diese Person wichtig, eine ihrer Eigenschaften ist eben der Name.
Mit den anderen Zugriffsmethoden verhält es sich nicht anders.

Immer wieder liest man im Forum. Wie greift man auf die Methoden einer anderen Klasse zu, wo es sich doch um ein anderes Objekt oder eine andere Instanz (egal welcher Klasse) handelt. Würde die Frage so gestellt, dann würde sie selbst beantworten. Man würde das Objekt nennen und danach dessen Methode ansprechen.
du meinst ich brauche eine Instanz der Klasse in der die Methode ist, um dann die Methode aufzurufen?
 

Neumi5694

Top Contributor
du meinst ich brauche eine Instanz der Klasse in der die Methode ist, um dann die Methode aufzurufen?
Genau. Sobald du das Prinzip von Objekten mit Eigenschaften oder Objekten mit Zugriffsmethoden einmal verinnerlicht hast, werden sich viele deiner Fragen zum Coden von selbst beantworten.

Es hilft, wenn du den Quellcode erst mal ignorierst und in Worten beschreibst, was du machen willst, ohne Begriffe wie "Klasse" oder "Methode" zu verwenden. Wenn du z.B. so was sagst wie: "Ich möchte den Namen dieser Person wissen", dann kannst du das Ganze meistens fast 1:1 in Quelltext umsetzen:
Code:
diesePerson.getName()
. Und damit weißt du auch, dass die Klasse Person eine nicht statische Name-Eigenschaft braucht.
Das ist jetzt nur ein einfaches Beispiel, aber grundsätzlich funktioniert alles nach diesem Prinzip.

Es gibt ein paar Programmierhilfen wie Struktogramme, die einem dabei helfen, einen Ablauf zu planen und beschreiben ohne zu coden.
Für das Design der Klassen und deren Eigenschaften gibt es eigene Hilfsmittel (UML zum Beispiel). Aber das A und O ist eben, dass man in Worten ausdrücken kann, was man eigentlich will. Und wenn man das ordentlich schafft, ist der Code meist nur noch Formsache.
 

Neue Themen


Oben