Funktionen miteinander verketten

Robertop

Aktives Mitglied
Hallo zusammen,

ich würde mir gern eine Klasse schreiben, mit der ich Funktionen "verketten" kann, um beim Programmieren natürlichere Ausdrücke verwenden zu können. Also ein einfaches Beispiel wäre sowas wie

Java:
stageObject.first("Hallo").second("Welt!");

Leider fehlt mir für sowas ein wenig das theoretische Wissen. Meine Idee bisher ist, dass ich eine Klasse mit einer inneren Klasse schreibe, die dann als Rückgabetyp der ersten Funktion ausgegeben wird, sodass man ab da die zweite Funktion benutzen kann:

Java:
public class Stage {
    
    private String string1 = "";

    private class SecondStage {
        private SecondStage() {}
        
        public void second(String string) {
            System.out.println(string1 + " " + string);
        }
    }
    
    public SecondStage first(String string) {
        string1 = string;
        return new SecondStage();
    }
}


Dazu habe ich jetzt diese Fragen:

- Ist das ein guter Weg, das zu lösen, oder gibt es da andere Vorgehensweisen? Wonach müsste ich bei google Suchen, um sowas zu finden? Bei meinen Versuchen finde ich immer nur alles mögliche zu Vererbung und Interfaces und so.

- Ist sichergestellt, dass der Inhalt von string1 beim Aufruf von second() immer richtig ist? Bei meinen Versuchen hat es immer funktioniert, aber im Prinzip erstelle ich ja in der first() Funktion ein neues Objekt von SecondStage(). Wird dieses neue Objekt wirklich in allen Lebenslagen mit demselben schon bestehenden Objekt von Stage zusammenhängen?

- Es soll natürlich am besten gar nicht möglich sein, ein alleinstehendes SecondStage Objekt zu bekommen. Am liebsten wäre mir sogar, wenn man sowas wie Object object = stage.first("Hallo"); gar nicht machen kann. Kann man das irgendwie verhinden?
 

kneitzel

Top Contributor
Also wenn Du googlen willst, wie sowas aufgebaut werden könnte, dann wäre z.B. Builder Pattern etwas, das so in der Art aufgebaut ist. Aber auch bei den Streams findet man sowas (inc. Wechsel des Typs z.B. bei map) wobei da Google vermutlich mehr zur Nutzung von Streams auswerfen wird denn zu der Entwicklung der Streams und dessen Design selbst.

Die innere Klasse hat den klaren Bezug zur äußeren Klasse - das wird also funktionieren, aber generell ist da natürlich nichts geschützt. Ich kann first aufrufen und die SecondStage in eine Variable packen um dann ggf. erst noch andere Aufrufe zu machen. Also z.B. sowas:
Java:
Stage stage = new Stage();
Stage.SecondStage second1 = stage.first("Hallo");
Stage.SecondStage second2 = stage.first("Na");
second1.second("Welt");
second2.second("Du");

Durch den zweiten Aufruf wird string1 natürlich überschrieben.
 

Robert Zenz

Bekanntes Mitglied
- Ist das ein guter Weg, das zu lösen, oder gibt es da andere Vorgehensweisen?

Das kommt darauf an was genau du vorhast. Ich glaube was du vorhast ist eine Unterform vom Builder-Pattern, naemlich das Step-Builder Pattern. Bricht man sich zwar fast die Finger beim tippen, ist aber echt eine coole Sache fuer denjenigen der es danach benutzt.
Ist sichergestellt, dass der Inhalt von string1 beim Aufruf von second() immer richtig ist?

Definiere "richtig". Wenn du meinst "es ist genau dieser Wert welcher vorher gesetzt wurde", dann Ja, es ist immer richtig. Innere Klassen in Java, welche nicht statisch sind, halten sich eine Referenze auf die Instanz ihrer Eltern-Klasse. Also so um das etwas zu veranschaulichen:

Java:
public class Outer() {
    protected int theValue = 4;
    
    public Inner setTheValue(int theValue) {
        this.theValue = theValue;
        
        return new Inner();
    }
    
    protected class Inner {
        public void doSomething() {
            System.out.println(theValue);
        }
    }
}

Sieht in "Wahrheit" wenn es ausgefuehrt wird so aus:

Java:
public class Outer() {
    protected int theValue = 4;
    
    public Inner setTheValue(int theValue) {
        this.theValue = theValue;
        
        return new Inner(this);
    }
    
    protected class Inner {
        protected Outer outerInstance = null;
        
        public Inner(Outer outerInstance) {
            this.outerInstance = outerInstance;
        }
        
        public void doSomething() {
            System.out.println(outerInstance.theValue);
        }
    }
}

Also die Referenz auf diese Instanz der aeusseren Klasse ist eindeutig.

Es soll natürlich am besten gar nicht möglich sein, ein alleinstehendes SecondStage Objekt zu bekommen. Am liebsten wäre mir sogar, wenn man sowas wie Object object = stage.first("Hallo"); gar nicht machen kann. Kann man das irgendwie verhinden?

Nein. Was genau versuchst du da zu bezwecken damit?
 

mihe7

Top Contributor
Es soll natürlich am besten gar nicht möglich sein, ein alleinstehendes SecondStage Objekt zu bekommen. Am liebsten wäre mir sogar, wenn man sowas wie Object object = stage.first("Hallo"); gar nicht machen kann. Kann man das irgendwie verhinden?
Jein. Natürlich kannst Du nicht verhindern, dass der Aufrufer den Rückgabewert verwendet, allerdings kannst Du durch dessen Typ einschränken, wofür er verwendet werden kann.

Mal ein einfaches Beispiel:
Java:
public class Car {
    public static class Builder {
        private String brand;
        private String model;
        public Builder brand(String value) { this.brand = value; return this; }
        public Builder model(String value) { this.model = value; return this; }
        public Car build() {
            if (brand == null || model == null || brand.trim().isEmpty() || model.trim().isEmpty()) {
                throw new IllegalStateException();
            }
            return new Car(this);
        }
    }

    private final String brand;
    private final String model;

    private Car(Builder builder) {
        brand = builder.brand;
        model = builder.model;
    }
}
Du kannst also nicht verhindern, dass jemand
Java:
Car.Builder b = new Car.Builder().brand("ABC");
schreibt. Allerdings muss Dich das nicht interessieren, weil Du kein unvollständiges Car-Objekt erzeugen kannst. Ein
Java:
Car car = b.build();
führt hier zu einer IllegalStateException. Schreibst Du dagegen:
Java:
Car.Builder b = new Car.Builder().brand("ABC");
b.model("1"); // oder b = b.model("1");
Car car = b.build();
funktioniert das natürlich genauso wie
Java:
Car car = new Car.Builder().brand("ABC").model("1").build();
 

kneitzel

Top Contributor
Evtl. hilfreich, da noch den Hinweis klar zu sagen:
Eben keine Werte in der äußeren Klasse haben.
a) Innere Klasse static halten -> Damit hast Du keine Verbindung zu einer äußeren Klasse, dern Zustand für Dich relevant ist.
b) (mit durch a bedingt) Du speicherst keine Werte in der äußeren Klasse. Also in Deinem Beispiel: Kein string1, das es sich daher holt.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Methoden Methoden anpassen und fehlende Funktionen hinzufügen Allgemeine Java-Themen 475
N Parser - Zerlegen verschachtelter Funktionen Allgemeine Java-Themen 2
A lineare funktionen und winkel Allgemeine Java-Themen 4
M JMuPDF Funktionen Allgemeine Java-Themen 0
S Funktionen von jre7 fehlen in jre8 Allgemeine Java-Themen 2
Tarrew RMI Java RMI - com.sun.proxy.$Proxy1 cannot be cast to Funktionen Allgemeine Java-Themen 0
A Funktionen aufrufen nach Schema x Allgemeine Java-Themen 2
C Benutzereingabe von EXCEL-Funktionen parsen Allgemeine Java-Themen 4
D Annotationen oder anonyme Funktionen? Allgemeine Java-Themen 0
N Algorithmus zum bewerten von mathematischen Funktionen Allgemeine Java-Themen 11
K Eclipse Mathematische Funktionen Allgemeine Java-Themen 8
T Parallelisierung zweier BigInteger-Funktionen Allgemeine Java-Themen 6
S Programmfehler bei grundlegenden Funktionen Allgemeine Java-Themen 6
ruutaiokwu threads bei klassen mit stat. funktionen... Allgemeine Java-Themen 2
S Profiler-Funktionen in eigener Applikation nutzen..? Allgemeine Java-Themen 5
X Quellcode von nativen Funktionen Allgemeine Java-Themen 2
J Zugriff auf gemeinsame Funktionen Allgemeine Java-Themen 4
B webservice stub enthält nicht genug funktionen Allgemeine Java-Themen 2
M Schnelle Scriptsprache für einfache Funktionen? Allgemeine Java-Themen 5
D Kompakte Syntax für Funktionen Allgemeine Java-Themen 7
D Parser-generator für mathematische Funktionen Allgemeine Java-Themen 12
R Problem mit Trigonometrischen Funktionen Allgemeine Java-Themen 16
N forschleife durchläuft funktionen Allgemeine Java-Themen 7
S reelle Funktionen Formel Allgemeine Java-Themen 13
A Funktionen werden im Jar-File nicht ausgeführt Allgemeine Java-Themen 6
M GUI ähnliche Elemt. und Funktionen im Browser - Technologie? Allgemeine Java-Themen 8
H Programmerweiterung durch Datei die Funktionen enthält Allgemeine Java-Themen 5
M Verkettung von 2 Funktionen? Allgemeine Java-Themen 4
A in patterns funktionen aufrufen Allgemeine Java-Themen 3
märliprinz Sortieren und Filtern von Funktionen/Methoden Allgemeine Java-Themen 4
F Aus Java heraus WinAPI Funktionen benutzen Allgemeine Java-Themen 7
W Problem mit sin- und cos-Funktionen Allgemeine Java-Themen 2
S Auf statische Funktionen mit Java Reflections zugreifen Allgemeine Java-Themen 3
C Funktionen einer dll aufrufen Allgemeine Java-Themen 3
T Meine Frage lautet wie ich 2 CSV Dateien miteinander in Java verbinde und Spalten die zueinander gehören durch den gleichen Key zusammen ausgebe? Allgemeine Java-Themen 5
J Mockito - Objekte miteinander vergleichen (equals) Allgemeine Java-Themen 6
Y inhalte aus 2 unterschiedlichen Arrays miteinander vergleichen Allgemeine Java-Themen 12
L Zwei Files miteinander vergleichen und Grafisch darstellen Allgemeine Java-Themen 1
H Zwei unabhängige Threads miteinander kommunizieren lassen Allgemeine Java-Themen 3
D mehrere Programme miteinander kommunizieren lassen Allgemeine Java-Themen 12
B zwei Bilder miteinander vergleichen Allgemeine Java-Themen 25
C Java Hauptprogramme miteinander verknüpfen Allgemeine Java-Themen 7
Luma Uhrzeiten miteinander vergleichen Allgemeine Java-Themen 5
C Sounddateien verketten Allgemeine Java-Themen 4
M .txt Datei öffnen und jede Zeile mit festem String verketten Allgemeine Java-Themen 5

Ähnliche Java Themen


Oben