【问题标题】:How do i avoid using if-else in this code?如何避免在此代码中使用 if-else?
【发布时间】:2018-08-15 21:30:00
【问题描述】:

作为我学习过程的一部分,我正在用 Java 创建一个小程序,该程序将帮助一家虚构的公司帮助销售汉堡。

在下面的代码中,我为汉堡创建了类,并添加了选项以向该汉堡添加添加物(如生菜、胡萝卜等)。

我面临的问题是如何在不过多使用 if-else 的情况下检查基本汉堡包(基本汉堡包仅表示面包和肉)的每个额外添加。我尝试的一种方法(您也可以在代码中看到)是为每个添加分配一个数字,例如,1 到生菜,2 个胡萝卜等等。通过添加 1 和 2 我们得到 3;我们可以寻找 3 来确定是否添加了生菜和胡萝卜,以便我们可以计算价格。我也用其他选项做到了这一点。

但是出现了一些问题:

  1. 在某些情况下,通过加法生成的数字会从不同的加法中创建两次,这可以通过将数字乘以某个数字或在创建更多边缘情况时加 1 来解决。

  2. 通过创建此类案例,我的主要问题是它需要大量 if-else 语句,我试图避免这些语句,以便有效地编写我需要的代码。

请建议是否有其他方法可以做到这一点。请注意代码尚未完成,因为我不想创建更多 if-else 语句(在汉堡类中;方法 cal_price)来检查添加内容,但足以完全理解代码的性质。代码如下:

public class Main {

    public static void main(String[] args) {
    Breadroll breadroll_type = new Breadroll("Sesame Seed Bun");
    meat meat_type = new meat("Beef");
    Hamburger my_burger = new Hamburger("Hamburger",breadroll_type,meat_type);
    my_burger.select_items(1,2,3,4);
    my_burger.cal_price();

    my_burger.getBreadroll_type();
    my_burger.getMeat_type();
    }
}
public class Breadroll {
    private String breadroll_type;

    public Breadroll(String breadroll_type) {
        this.breadroll_type = breadroll_type;
    }

    public String getBreadroll_type() {
        return breadroll_type;
    }
}
public class meat {
    private String meat_type;

    public meat(String meat_type) {
        this.meat_type = meat_type;
    }

    public String getMeat_type() {
        return meat_type;
    }
}

public class Hamburger {

    private String name;
    Breadroll breadroll_type;
    meat meat_type;
    private double base_price; //Price without addons
    private int lettuce;
    private int carrot;
    private int tomato;
    private int cheese;
    private int hot_sauce;
    private  int mustard;
    private int total_select;

    public Hamburger(String name, Breadroll breadroll_type, meat meat_type) {
        this.name = name;
        this.breadroll_type = breadroll_type;
        this.meat_type = meat_type;
        this.base_price = 2.75;
    }


    public void select_items(int lettuce, int carrot, int tomato, int cheese) {

        this.lettuce = lettuce;
        this.carrot = carrot;
        this.tomato = tomato;
        this.cheese = cheese;
        this.total_select = lettuce + carrot + tomato + cheese;


    }


    public void cal_price()
    {
        double final_price;
        double lettuce_price = 0.50;
        double carrots_price = 0.60;
        double tomatos_price = 0.70;
        double cheese_price = 0.85;

        if(total_select == 0) {
            System.out.println("Order Placed : Hamburger with no additions " + getBase_price() + "$");
        }


        else if (total_select == 1) {
            final_price = getBase_price() + lettuce_price;
            System.out.println("Order Placed : Hamburger with all lettuce " + (float) final_price + "$");
        }
        else if (total_select == 2) {
            final_price = getBase_price() + carrots_price;
            System.out.println("Order Placed : Hamburger with all carrot " + (float) final_price + "$");
        }
        else if (total_select == 3) {
            final_price = getBase_price() + tomatos_price;
            System.out.println("Order Placed : Hamburger with all tomato " + (float) final_price + "$");
        }
        else if (total_select == 4) {
            final_price = getBase_price() +cheese_price;
            System.out.println("Order Placed : Hamburger with all cheese " + (float) final_price + "$");
        }
        else if (total_select*100 == 1000) {
            final_price = getBase_price() + lettuce_price + carrots_price + tomatos_price + cheese_price;
            System.out.println("Order Placed : Hamburger with all additions " + (float) final_price + "$");
        }

    }

    public String getName() {
        return name;
    }

    public void getBreadroll_type() {
        System.out.println(breadroll_type.getBreadroll_type());
    }

    public void getMeat_type() {
        System.out.println(meat_type.getMeat_type());
    }

    public double getBase_price() {
        return base_price;
    }

    public int getLettuce() {
        return lettuce;
    }

    public int getCarrot() {
        return carrot;
    }

    public int getTomato() {
        return tomato;
    }

    public int getCheese() {
        return cheese;
    }
}

【问题讨论】:

  • 看看switch 声明。
  • @JacobG。您能否添加一个类似于我的代码的示例?这对我有很大帮助。
  • 为什么您的某些 get 语句打印信息而不是返回信息?为什么您的商品价格不是静态常量?为什么你不必要地将总选择乘以100?为什么你的底价是一个实例变量?为什么只有一个类以小写字母开头?如果人们订购的商品数量不限,会发生什么?
  • 您可能需要考虑在CodeReview StackExchange 上发帖以获取有关您代码的反馈。

标签: java oop optimization


【解决方案1】:

您对“汉堡包”对象的实现似乎有点过于复杂。通常面向对象的编程来表示实际的物理对象,应该尽可能选择最简单、最原子的属性来避免这种情况。一个汉堡要么有生菜,要么没有生菜。它要么有番茄,要么没有番茄。我的建议是为每个浇头使用单独的布尔变量,或者如果您愿意,可以使用一个表示浇头的布尔数组。然后,将 get_price() 方法添加到您的汉堡包中,该方法有一个用于计算价格的 if 语句块。如果您真的想进入 OOP,每个浇头都可以是一个带有价格的对象,您可以将其附加到汉堡包上的 Toppings ArrayList 中。然后,您的 get_price() 方法将使用一个 for-each 来总计您的 Topping 对象的所有价格,以及您的汉堡包的价格属性。如果您想要多个数量的相同浇头,此方法可能会更好。这是编程的乐趣所在 - 您可以选择对您最有意义的实现并进行尝试!

【讨论】:

    【解决方案2】:

    制作了一个带有名称,面包类型,肉类类型的汉堡包,稍后添加额外的,你也可以为面包类型和肉类制作单独的方法。在额外的方法中,我们预先计算了额外的价格,因此调用 getPrice() 将所有额外的价格与所选的面包/肉类类型相加。还有其他方法可以做到这一点,但这样你也会有一个合同和 switch 语句的例子。删除了一些成分,但你明白了。

    还要看看命名约定与您的有何不同。

    class HamburgerContract {
    
    // Specify your constants in this class so all classes are able to communicate with the same values
    // Change the name to something shorter like HBC for easier reference, ie HBC.BR_TYPE_SESAM
    
    public static final int BR_TYPE_SESAM = 1;
    public static final int BR_TYPE_HONEY = 2;
    
    public static final int MEAT_TYPE_COW = 1;
    public static final int MEAT_TYPE_CHICKEN = 2; 
    }
    
    public class Hamburger {
    
    public static void main(String[] args) {
    
        // Made a hamburger with name, breadtype, meattype and added the extra's later on
        // You can make seperate methods for the breadtype and meat as well
        // In the extra methods we calculate the extra price beforehand
        // So calling getPrice() sums up all the extras with chosen bread/meat type
        // There are other ways to do this but this way you'll also have an example of a contract and switch statement
        // Removed a few ingredients but you get the point
    
        Hamburger myHamburger = new Hamburger("Varadero Burger", HamburgerContract.BR_TYPE_SESAM, HamburgerContract.MEAT_TYPE_CHICKEN, 2.50);
        myHamburger.addCarrot();
        myHamburger.addLettuce();
        myHamburger.removeCarrot();
        System.out.print("The price of your " + myHamburger.getName() + "is $ " + myHamburger.getPrice());
    }
    
    private String burgerName;
    private int breadrollType;
    private int meatType;
    
    private boolean lettuce;
    private boolean carrot;
    
    private double basePrice;
    private double extraPrice;
    
    public Hamburger(String burgerName, int breadrollType, int meatType, double basePrice) {
    
        this.burgerName = burgerName;
        this.breadrollType = breadrollType;
        this.meatType = meatType;
        this.basePrice = basePrice;
    
        this.extraPrice = 0;
    
        this.lettuce = false;
        this.carrot = false;
    }
    
    
    
    public void addLettuce() {
        // extra check if lettuce is not already added, so you wont add to the price twice
        // same goes for removing the lettuce or the carrot methods
        if (!lettuce) {
            letuce = true;
            extraPrice += 0.25;
        }
    }
    
    public removeLettuce() {
        if (lettuce) {
            letuce = false;
            extraPrice -= 0.25;
        }
    }
    
    public void addCarrot() {
        if (!carrot) {
            carrot = true;
            extraPrice += 0.20;
        }
    }
    
    public void removeCarrot() {
        if (carrot) {
            carrot = false;
            extraPrice -= 0.20;
        }
    }
    
    public String getName() {
        return burgerName;
    }
    
    public double getPrice() {
    
        switch (breadrollType) {
            case HamburgerContract.BR_TYPE_HONEY: extraPrice += 0.25; break;
            case HamburgerContract.BR_TYPE_SESAM: extraPrice += 0.50; break;
        }
    
        switch (meatType) {
            case HamburgerContract.MEAT_TYPE_COW: extraPrice += 0; break;
            case HamburgerContract.MEAT_TYPE_CHICKEN: extraPrice += 0.50; break;
        }
    
        return basePrice + extraPrice;
    
    } 
    }
    

    【讨论】:

      【解决方案3】:

      您根本不需要使用条件语句,只需将每件商品的价格乘以其价格即可:

      final_price = getBase_price()
          + lettuce_num * lettuce_price
          + carrots_num * carrots_price
          + tomatos_num * tomatos_price
          + cheese_num * cheese_price;
      

      在您的设置方法中,您应该设置项目的数量/数量(例如,生菜),而不是 1 == 生菜和 2 == xxx:

      my_burger.select_items(5,0,0,0); // 5 lettuce, 0 all other
      my_burger.select_items(1,0,0,90); // 1 lettuce, 90 cheese, 0 all other
      

      把它们放在一起(缩小):

      public class Main {
          public static void main(String[] args) {
              Hamburger my_burger = new Hamburger("Hamburger");
              my_burger.select_items(
                  100, // 100 lettuce
                  0,   // 0 carrot
                  2,   // 2 tomato
                  1);  // 1 cheese
              my_burger.cal_price();
          }
      }
      
      public class Hamburger {
          private String name;
          private double base_price = 2.75;
          private int lettuce;
          private double lettuce_price = 0.50;
          private int carrot;
          private double carrots_price = 0.60;
          private int tomato;
          private double tomatos_price = 0.70;
          private int cheese;
          private double cheese_price = 0.85;
      
          public Hamburger(String name) {
              this.name = name;
          }
      
          public void select_items(int lettuce, int carrot, int tomato, int cheese) {
              this.lettuce = lettuce;
              this.carrot = carrot;
              this.tomato = tomato;
              this.cheese = cheese;
          }
      
          public void cal_price()
          {
              double final_price = getBase_price()
                  + lettuce * lettuce_price
                  + carrots * carrots_price
                  + tomato * tomatos_price
                  + cheese * cheese_price;
              // TODO print price
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-29
        • 1970-01-01
        • 2012-08-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多