If-Else abfrage per Drag and Drop erstellen

Hallo,

für ein Programm muss ich eine Reihe von If-Else abfragen, mit vielen Verzweigungen erstellen. Das zu Programmieren ist eine Menge Arbeit, zumal die Verzweigungen immer wieder aufeinander aufeinander verweisen. Im Prinzip sowas:

- nur mit Deutlich mehr Inhalt.

Einfacher (und übersichtlicher) wäre es, wenn es die Möglichkeit gäbe das ganze grafisch zu erstellen. Vermutlich werde ich Pech haben und so ein Programm gibt es nicht (was auch erklärt, dass ich nicht im Internet gefunden habe, aber falls doch wäre das eine erheblich Hilfe.

Wie sowas aussehen sollte, ist nicht ganz klar. Was sollte die Eingabe und was die Ausgabe sein? Selbst bei der vermeintlich klaren Anforderung “Es soll quellcode rauskommen” wäre die Frage der Form noch nicht klar, und die Frage nach der Eingabe noch entscheidend.

Wenn man da so draufschaut:
“Du möchtest mehr über Googles Entwicklung und Kanalübergreifende Werbung erfahren?”
Wie sollte eine if-Abfrage dafür aussehen?

if (youWantToKnowMoreAboutGoogleDevelopmentAndWhateverKanalübergreifendHeißtAdvertising()) {
    // ?!?!
}

!?

Nun, beim ersten drübergucken über den Screen finde ich zumindest in diesem bestimmten keine Rekursionen. Das lässt sich dann noch halbwegs einfach in einem Baum packen. Wenn du allerdings einen Graph hast der auch rekursive Pfade zulässt - du also nach einer bestimmten Auswahl irgendwann wieder am gleichen Punkt ankommst - dann dürfte es schon schwerer werden - falls überhaupt sinnvoll möglich.

Wie könnte sowas abgehen? Man kennt im Netz diverese Möglichkeiten - da du aber bewusst auf drop-downs angesprochen hast - das gibt es auch. Ich kann dir jetzt zwar direkt kein Beispiel nennen, aber ich kenne eine solche Eingabe dass man oben die erste Frage beantwortet und dann on-the-fly auf Basis der Antwort die Möglichkeiten für das zweite Drop-Down raussucht und dann aktiviert - bis man am Ende des Zweigs angekommen ist und quasi die Antwort hat.
Letztlich wirst du intern nicht um if-else herum kommen - aber sehr wohl über ein ewig tiefes if-else-if-else-etc (Stichwort: code-re-use).

Die Umsetzung wäre dann z.B. eine Methode getPossibleAwnsers(Choice) der man als Parameter die vorherige Auswahl übergibt. Um jetzt das if-else nicht in dieser Methode zu verstecken wäre es sinnvoll vorher einen Baum oder eine ähnliche Datenstruktur, ggf. auch in einer Datenbank, abzubilden. So kannst du z.B. an die Datenbank ein SELECT awnsers FROM table WHERE choice='choicex' absetzen und bekommst die nächsten möglichen Antworten die du dann wieder ins drop-down (müsste dann AFAIR JComboBox sein sofern mit Swing gearbeitet wird) werfen und mit einem Listener dann auf eine Auswahl des Users warten (dürfte in dem Fall ein normaler ActionListener sein (gerade mal in die doc geguckt - public class … implements ActionListener - OUCH)).

Moin,

imho ist der TO ein Anfänger, der einen Zustandsautomaten schreiben will (vermutlich ohne das zu wissen). Seine Lösung ist imho 1 Trillion if/else Anweisungen in eine Klasse zu dengeln. Da davon die Tastatur kaputt geht, sucht er imho ein Tool mit dem man den Quelltext zusammen klicken kann.

Sollte dem so sein, versuche mal ob Du diesen Quelltext verstehst:



import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;


public class Main {

    enum State {

        HUNGRY("Hungrig?"),
        BREAKFAST("Gefrühstückt?"),
        LUNCH("Zu Mittag gegessen?"),
        DINNER("Zu Abend gegessen?"),
        EAT("Iss etwas!"),
        LIAR("Du bist nicht hungrig!");

        final String text;


        State(final String text) {
            
            this.text = text;
            
        }


        @Override
        public String toString() {

            return text;
            
        }

    }


    private final Map<State, State> noTransition = new HashMap<>();
    private final Map<State, State> yesTransition = new HashMap<>();


    public Main() {

        addTransition(State.HUNGRY, State.HUNGRY, State.BREAKFAST);
        addTransition(State.BREAKFAST, State.EAT, State.LUNCH);
        addTransition(State.LUNCH, State.EAT, State.DINNER);
        addTransition(State.DINNER, State.EAT, State.LIAR);
        addTransition(State.EAT, State.EAT, State.HUNGRY);
        addTransition(State.LIAR, State.HUNGRY, State.HUNGRY);

    }


    private void addTransition(final State current, final State no, final State yes) {

        noTransition.put(current, no);
        yesTransition.put(current, yes);

    }


    public void run() {

        final Scanner s = new Scanner(System.in);

        State state = State.HUNGRY;
        while (true) {

            System.out.println(state);

            switch (s.next().charAt(0)) {

            case 'n':
                state = noTransition.get(state);
                break;

            case 'y':
                state = yesTransition.get(state);
                break;

            }

        }

    }


    public static void main(final String[] args) {

        new Main().run();

    }

}

Wenn Du die Abstraktion dabei verstehst, kannst Du die Übergänge zwischen den einzelnen Zuständen auch genauso gut aus einer Datei einlesen. Dann brauchst Du kein einziges if/else.

Gruß
Fancy

Hallo ihr beiden,

vielen Dank für Eure Antworten. Fancy Du hast ganz recht, was ich suchte war ein Zustandsautomat - der Ausdruck war mir bislang noch nicht bekannt. Immer schön wenn man was dazulernt.

Vielen Dank auch für das Programm. Das man das Konzept mit so wenig Code verwirklichen kann hätte ich nicht gedacht.

Leider muss ich dazu noch ein Frage stellen. Wie kann ich das Programm beenden? Beispielsweise, dass nach der Ausgabe von LIAR das Programm aufhört?

[edit SlaterB: Beitrag war erst freizuschalten, deswegen sicher zweiter ähnlicher darunter]

Vielen, vielen Dank für die hilfreichen Antworten.

Doch ich muss leider noch ein Frage zu dem großartigen Programm von Fancy stellen. Wie kann ich das Programm, beispielsweise nach der Ausgabe von LIAR beenden, anstatt es eine Dauerschleife auszuführen. Ich habe noch nie mit Enums und Switch-Case gearbeitet.

Vielen Dank im Voraus.

Du musst lediglich dafür sorgen, dass die Dauerschleife beendet wird. Beispielsweise durch:

while (state != State.LIAR) {
  // ...
}

Du kannst einen End-State einführen (natürlich muss es auch Wege geben, dahin zukommen), dann musst du in der Schleife nur noch ein while(state != State.END) { verwenden.