Vererbung If-Else ersetzen durch was?

lam_tr

Top Contributor
Hallo zusammen,

ich hab mal gehört dass man If-Else vermeiden soll und stattdessen Vererbungen benutzt.

Ich weiss aber nicht genau wie ich es für meinen Fall anwenden kann.
Vielleicht könnt ihr mir da weiterhelfen.

Ich habe eine Methode sie vergleicht sozusagen 2 Datum mit verschiedene if-else Statements.

z.B.

if(betweenDays(date1, date2)>0){
// mache was mit date1
}else if(notLastDayOfMonth(date1)){
// mache was mit date1
}else if(notLastDayOfMonth(date1)){
// mache was mit date1
}

Wie kann man das ganze etwas schöner gestalten?

Viele Grüße
lam
 
Moin,

ich hab mal gehört dass man If-Else vermeiden soll und stattdessen Vererbungen benutzt.
Diese Aussage verstehe ich nicht !
"if-else" ist eine Fallunterscheidung und hat nichts mit "Vererbung" zu tun !!

Java:
if(betweenDays(date1, date2)>0)
{
    // mache was mit date1
}
else if(notLastDayOfMonth(date1))
{
    // mache was mit date1
}
else if(notLastDayOfMonth(date1)) // DU HAST HIER DIE GLEICHE BEDINGUNG --> dürfte einen Compilerfehler geben !!
{
    // mache was mit date1
}
Manchmal ist ein "switch" optisch schöner, aber funktional ist es eh' egal, somit könntest Du das so lassen - bis auf meine Bemerkung im Code!!

Gruß
Klaus
 
Hallo klaus, danke für deine Antwort.

Ich finde bei IF/Else Anweisung ist es so dass, wenn ich aktuell 3 Anweisungen habe und will später noch um 10 weitere unterscheiden, dann muss ich überall mitziehen. Deshalb ist es nicht so toll.

Nach ein bissle Googlen habe ich das hier gefunden http://stackoverflow.com/questions/22953136/alternative-of-if-else-and-switch-Statements

Alle Unterscheidungen in eine Map zu initialisieren. Macht das mehr Sinn?

Falls ja, wenn ich in der Klasse A, B , C die Map benutze, wo initialisere ich sie am Besten, und wie reiche ich sie weiter?

Gruß
lam
 
Ich habe zwei weitere Alternativen gefunden, bin mir aber nicht sicher ob es so sinnvoll ist.

Polymorphismus:
Code:
interface SomethingDoer {
    public void doSomething();
}

class ADoer implements SomethingDoer { ... }
class BDoer implements SomethingDoer { ... }
class CDoer implements SomethingDoer { ... }

public class Main {
     public static void main (String[] args) {
          SomethingDoer doer = new SomethingDoerFactory(args).getDoer();
          doer.doSomething();
     }
}

Oder in Liste anstatt Map:
Code:
List<Rule> rules = .... ; // your 3 rules initialized here somehow
for(Rule r : rules) {
  if(r.condition()) {
    r.action();
  }
}

An sich sind das 3 schöne Vorgehensweise, aber wie geht man wirklich vor in meinem Fall?
 
ich hab mal gehört dass man If-Else vermeiden soll und stattdessen Vererbungen benutzt.
Das bezieht sich auf dieses Pattern: http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html
Statt einer Vererbung kann man da auch das Strategy-Pattern verwenden.
Allerdings bin ich mir nicht sicher, ob das auf deinen Anwendungsfall passt. Hier geht es vor allem darum, dass eine Eigenschaft eines Objekts immer wieder eine Fallunterscheidung benötigt.
 
Hallo Dompteur,

das Polymorphismus Pattern sieht meiner Meinung sehr gut aus, aber mir fehlt noch der Gedanke wie ich die Fallunterscheidung in das Object verpacke?

Soll ich etwa wieder Bedingungen abfragen und das passende Bird zurückgeben lassen?

z.B:
Bird bird = null;
if(type== Type.EUROPEAN){
bird = new EuropeanBird();
}else if(type == Type.AFRICAN){
bird = AfricanBird();
}else if(type== Type.NORWEGEAN){
bird = new NorwegeanBird();
}

println(bird.getSpeed());


Ich finde, da komme ich dann trotzdem nicht drumrum die if/else zu benutzen.
 
Gerade in dem von dir genannten Fall würde sich eher etwas anbieten, wie
Java:
Bird bird = type.createBird()

Auch in enums kannst du Methoden usw definieren...
 
Zuletzt bearbeitet:
@VfL_Freak Nur so am Rande, das ginge schon, ist unter Umständen sogar gewollt. Jedoch würde ich jeden verjagen, der mir solchen Code präsentiert 🙂
Java:
public class Crap {  
    static boolean check = true;
     public static void main(String ... args) {
        if(check()) {
           System.out.println("1");
       }
       else if(check()) {
          System.out.println("2");
      }
     }
  
     static boolean check() {
       check = !check;
       return check;
    }
}
 
Hallo stg,

Code:
Bird bird = type.createBird()

Ich glaube ich bin etwas zu blöd dafür. Wo ist da die Unterscheidung um das richtige Vogel zu holen in dem Enum?

Und in meinem Fall passt es doch gar nicht oder? Wenn ich den Abstand zweier Daten, Ob Datum letzter Tag vom Monat oder Datum erster Tag vom Monat ist.

Wie kann man das am Besten verpacken?

Solche Fallunterscheidungen tendieren dazu, dass sie an mehreren Stellen vorkommen.
Der Sinn des Patterns ist es, dass du sie auf einer Stelle zusammenfasst.

Genau Dompteur, mein Ziel ist es zu zentralisieren, so dass ich nur noch an einer Stelle das verwalten muss. Aber ich komm einfach noch nicht auf die Idee.
 
Code:
Bird bird = type.createBird()

Ich glaube ich bin etwas zu blöd dafür. Wo ist da die Unterscheidung um das richtige Vogel zu holen in dem Enum?

Im enum!

Java:
enum Birds {
   EUROPEAN {
        public Bird createBird() { return new EuropeanBird(); }
   }
   // ...
  public abstract Bird createBird();
}
 
@lam_tr
Du könntest das Strategy Pattern verwenden und ein Interface definieren IHandleDate mit der Methode doIt.
Dann erstellst du für jeden Fall eine Klasse, die dein jeweiliges "mache was mit date1" in der Methode doIt implementiert.
Deine HandleDateFactory implementiert nun eine createHandleDate Methode, die die Fallunterscheidungen macht und die richtige Klasse erzeugt.

Dann sieht deine Verwendung so aus:
Java:
IHandleDate executor = HandleDateFactory.createHandleDate (date1, date2);
executor.doIt(date1);

Bei deinem konkreten Beispiel bringt das Pattern aber nur dann etwas, wenn du die gleiche if/else Sequenz an verschiedenen Stellen immer wieder verwenden musst.
Und auch nur dann, wenn du nicht schon den ganzen Block als Methode herausziehen kannst. ;-)
 
Oh man, ich glaube das StrategyPattern war wirklich das was ich gebraucht habe.
Ich werde mir dieses Pattern mal genauer angucken.

Vielen Dank euch beiden. Habe auf jeden Fall sehr viel dazu gelernt.
 
Hi Dompteur,

mir ist noch was aufgefallen du meintest Fallunterscheidung soll noch in der "createHandleDate Methode" gemacht werden, d.h. dort werden trotzdem if/else geben oder?

Gruss lam
 
@VfL_Freak Nur so am Rande, das ginge schon, ist unter Umständen sogar gewollt. Jedoch würde ich jeden verjagen, der mir solchen Code präsentiert 🙂
Java:
public class Crap { 
    static boolean check = true;
     public static void main(String ... args) {
        if(check()) {
           System.out.println("1");
       }
       else if(check()) {
          System.out.println("2");
      }
     }
 
     static boolean check() {
       check = !check;
       return check;
    }
}
ok, Du hast in soweit recht, das es sich wirklich compilieren und auch ausführen läßt!
Allerdings hat dieses Beispiel nur wenig mit Deinen Ursprungspost gemein!
Java:
if(betweenDays(date1, date2)>0)
{
    // mache was mit date1
}
else if(notLastDayOfMonth(date1))
{
    // mache was mit date1
}
else if(notLastDayOfMonth(date1))
{
    // mache was mit date1
}
Ich wollte darauf hinweisen, das hier die dritte Bedingung obsolet ist, da sie nie durchlaufen werden kann!
Ich hätte aber zwar jetzt genau deswegen einen Compiler-Fehler oder zumindest eine Warning erwartet, aber vlt. haben wir die auch beide ausgeschaltet!

Gruß Klaus
 
Danke Klaus, es war nur ein falsche Paste-Fehler.
Es sollte so heißen

Code:
if(betweenDays(date1, date2)>0)
{
     // mache was mit date1
}
else if(notLastDayOfMonth(date1))
{
     // mache was mit date1
}
else if(notFirstDayOfMonth(date1))
{
     // mache was mit date1
}

Deswegen soll Copy/Paste wirklich vermieden werden 🙂
 
Moin,
Deswegen soll Copy/Paste wirklich vermieden werden 🙂
Genau !! Tippfehler sind viel schöner 😀

Aber wenn Du eine simple Fallunterscheidung hast, ist grundlegend ein if-else oder ein switch das Mittel der Wahl!
Ob sich der o. g. Aufwand mit den Pattern wirklich lohnt, muss man wohl im Einzelfall entscheiden ...

Gruß Klaus
 
ok, Du hast in soweit recht, das es sich wirklich compilieren und auch ausführen läßt!
Allerdings hat dieses Beispiel nur wenig mit Deinen Ursprungspost gemein!
Java:
if(betweenDays(date1, date2)>0)
{
    // mache was mit date1
}
else if(notLastDayOfMonth(date1))
{
    // mache was mit date1
}
else if(notLastDayOfMonth(date1))
{
    // mache was mit date1
}
Ich wollte darauf hinweisen, das hier die dritte Bedingung obsolet ist, da sie nie durchlaufen werden kann!
Ich hätte aber zwar jetzt genau deswegen einen Compiler-Fehler oder zumindest eine Warning erwartet, aber vlt. haben wir die auch beide ausgeschaltet!

Gruß Klaus
Der Compiler liefert keine Warnung, da es sich um einen Methodenaufruf handelt. Und hier kann man natürlich trotz des gleichen Parameters auch verschiedene Ergebnisse bekommen.

@lam_tr
In dem Fall brauchst du dennoch eine Fall Unterscheidung, aber eben nur einmal und nicht an mehreren verschiedenen Stellen.
 
@InfectedBytes
Ahhh, jetzt blickt bei mir erst recht ein Lämpchen.
in der Factory-Klasse wird spezifiert und in allen anderen arbeite ich entweder mit Oberklasse oder Interface.

Sehr gut, danke schön!
 

Zurück
Oben