Switch durch OOP ersetzen



  • switch (result) { 
                case WIN: 
                    scorePlayer++; 
                    break; 
                case LOSE: 
                    scoreComputer++; 
                    break; 
                case DRAW: 
                    scoreDraw++; 
                    break; 
                }
    

    Wie kann man denn das hier mehr objektorientiert gestalten ? Switch Anweisungen sollen wohl wenn moeglich vermieden werden.



  • Besteht denn die Erwartung, daß es andere mögliche Ergebnisse eines Spielzugs geben könnte als Gewinn, Patt oder Verlust?



  • Ok, du bist ein erfahrener Java Entwickler (gibst DU zumindest an). Und nun brauchst du Hilfe bei einer simplen Programmieraufgabe, die dir im Rahmen einer Bewerbung auf eine Position gestellt wurde. Bzw. das Forum soll die Aufgabe für dich lösen und du willst die Aufgabe nicht mit einer richtigen Recherche lösen.

    Viel Erfolg bei der Stellensuche!


  • Mod

    DerBaecker schrieb:

    Ok, du bist ein erfahrener Java Entwickler (gibst DU zumindest an). Und nun brauchst du Hilfe bei einer simplen Programmieraufgabe, die dir im Rahmen einer Bewerbung auf eine Position gestellt wurde. Bzw. das Forum soll die Aufgabe für dich lösen und du willst die Aufgabe nicht mit einer richtigen Recherche lösen.

    Viel Erfolg bei der Stellensuche!

    +1. Wer hier hilft, verdient blurry333 als Kollegen!

    PS: Andererseits...Ich weiß dass das keine von unseren Bewerbungsaufgaben ist. Wenn ich ihm jetzt helfe, kommt er nicht zu uns, und ich kann meinem Chef sagen, ich hätte die Konkurrenz sabotiert 🙂



  • Besteht denn die Erwartung, daß es andere mögliche Ergebnisse eines Spielzugs geben könnte als Gewinn, Patt oder Verlust?

    nee, uebrigends die Firma hat mich schon abgelehnt. Ich hab extra nach einem feedback gefragt und da wurde eben darauf hingewiesen
    dass man statt switch eher was objektorientiertes verwenden soll. Wie koennte das denn grob aussehen ? Es muss ja nicht das gleiche Beispiel sein, kann ja irgendein switch sein..





  • Woher kommt denn diese Anforderung switches zu vermeiden? Klar mit Biegen und brechen kann man alles irgendwie durch OOP abbilden. Aber selbst hier sind einem Grenzen gesetzt in denen man dann doch wieder darauf zurück greifen muss.

    Für den verlinkten Fall mag das gehen. Aber spätestens, wenn wir ein Objekt haben, dass seinen Status als "Enum" hält, weil es halt notwendig ist und dieser Status ausgewertet werden muss, steht man wieder vor einem Switch.

    @computernerds
    Ich denke, das größte Problem bei dem von dir gezeigten Code ist das komplette fehlen von OOP. In der Regel hat man ein Spieler-Objekt. Meinetwegen auch mit Polimorphie, wo der Computer eben vom Spieler erbt.


  • Mod

    inflames2k schrieb:

    Woher kommt denn diese Anforderung switches zu vermeiden? Klar mit Biegen und brechen kann man alles irgendwie durch OOP abbilden. Aber selbst hier sind einem Grenzen gesetzt in denen man dann doch wieder darauf zurück greifen muss.

    Du beantwortest die Frage selbst:

    @computernerds
    Ich denke, das größte Problem bei dem von dir gezeigten Code ist das komplette fehlen von OOP. In der Regel hat man ein Spieler-Objekt. Meinetwegen auch mit Polimorphie, wo der Computer eben vom Spieler erbt.

    Dies ist ein Bewerbercase. Er soll an einem kleinen Beispiel zeigen, dass er die Grundlagen der modernen¹ Programmierung versteht und anwenden kann. Da schreibt man eben auch etwas so einfaches wie Schere-Stein-Papier test-driven, OOP, agil, cognitive, virtualisiert, und mit allen anderen Wörtern aus dem Buzzword-Duden, um zu zeigen, dass man es kann. Der TE hat jedoch stattdessen etwas abgeliefert, was aus dem ersten Drittel eines Anfängerlehrbuchs stammen könnte und wusste auf die Fragen, wie man das objektorientiert oder mit Tests machen könnte, keine Antwort.

    ¹: Oder eher: Der seit 20+ Jahren üblichen Programmierung.



  • inflames2k schrieb:

    Aber spätestens, wenn wir ein Objekt haben, dass seinen Status als "Enum" hält, weil es halt notwendig ist und dieser Status ausgewertet werden muss, steht man wieder vor einem Switch.

    Es sei denn man packt die Auswertung in das Enum.

    Was mir auf die Schnelle zum ursprünglichen Code einfällt:

    enum GameEndCondition {
      PLAYER1WIN() {
        @Override
        public void apply(Player player1, Player player2) {
          player1.increasePoints();
        }
      },
      PLAYER2WIN() {
        @Override
        public void apply(Player player1, Player player2) {
          player2.increasePoints();
        }
      },
      DRAW() {
        @Override
        public void apply(Player player1, Player player2) {
          player1.increasePoints();
          player2.increasePoints();
        }
      };
    
      public void apply(Player player1, Player player2) {}
    }
    
    // Ergebnis Auswertung ohne switch
    result.apply(player1, player2);
    


  • Switch-Case ist halt nicht skalierbar. Das ist das Problem. Es lässt sich nur durch manipulation des Sourcecodes erweitern.

    Polymorphie haben wir aber überall, ohne uns bewusst zu werden. Selbst so banale Dinge wie die Dateistreams von Unix sind polymorph. Ich kann meine Daten an jedem beliebigen Stream lesen und schreiben: egal ob ich auf den Bildschirm, Drucker, Festplatte, COM-Port usw Zeichen sende. Wenn ich heute nur einen Bildschirm als Output habe, und morgen einen Nadeldrucker an den COM-Port anschließe, muss ich keinen Sourcecode ändern. Ich muss nur den Stream umleiten. Wenn die *nix-Erfinder das per Switch-Case gelöst hätten, wäre das System nicht skalierbar und man müsste bei jedem neuen Port/Gerät erstmal den C-Code ändern und neu kompilieren. Aber es wird Polymorphie angewendet.

    Wenn wir reine OOP betreiben (ohne Konstanten und switch-case), machen wir die Polymorphie halt nur mit Klassen. Aber der Grundgedanke ist der gleiche.

    Intern machen die *nix-Streams und die OO-Polymorphie das gleiche: es wird eine VTable benutzt und der Pointer wird umgebogen.

    Switch-Case benutze ich heute nur noch, wenn ich mir sehr sicher bin, das morgen das Switch-Case nicht erweitert werden muss. Z.B. ist die Anzahl der Kalender-Monate ziemlich konstant. 😃



  • Irgendwo sammelt Blurry die Minuten eures Leben, die er euch entwendet hat. Und die gibt es nicht zurück ⚠



  • Artchi schrieb:

    Switch-Case ist halt nicht skalierbar. Das ist das Problem. Es lässt sich nur durch manipulation des Sourcecodes erweitern.

    Switch-Case benutze ich heute nur noch, wenn ich mir sehr sicher bin, das morgen das Switch-Case nicht erweitert werden muss. Z.B. ist die Anzahl der Kalender-Monate ziemlich konstant. 😃

    Also ich kam bislang mit switch immer super zurecht. Und wenn man das mal erweitern muss, dann fuegt man halt ein zusaetzliches case hinzu. Hm. Wahrscheinlich denk ich zu simple.

    Wenn man das ohne switch machen will, ist das erstmal ein riesiger Aufwand. Fuer jedes Case muss man dann eine Klasse anlegen, wenn ich das jetzt bzgl Polymorphie richtig verstanden habe.



  • dann fuegt man halt ein zusaetzliches case hinzu. Hm. Wahrscheinlich denk ich zu simple.

    trivial Beispiel wo das nicht geht - per Plugin dynamisch erweiterbar um weitere Varianten,

    oder negativ-Beispiel für hart kodiert - wenn du dann mal an 100 Stellen (z.B. 100 verschiedene Features deines "Objektes") dein case erweitern musst vergisst man das leicht


Anmelden zum Antworten