对于库存中的每件商品,“if”看起来很难看

时间:2015-10-17 15:07:19

标签: java

我现在正在学习java,对于一些练习我正在编写一个小游戏的库存。你有3个插槽,每个插槽你可以放一个项目。

public boolean useItem(int place){
    //out of array request?
    if (place > items.length) return false;
    //empty inventory place?
    if (items[place] == 0) return false;

    if (items[place] == 1){
        //eat berrys
        items[place] = 0;
        return true;
    }
    if (items[place] == 2){
        //shoot arrow
        items[place] = 0;
        return true;
    }
    //item not there
    return false;
}

它有效,但是为每一个项目写下越来越多的“if”感觉很糟糕。有谁知道更好的解决方案?

4 个答案:

答案 0 :(得分:5)

Item item = items[place]; // by default you can have an EmptyItem that does nothing in the inventory when the place is empty

现在让我们想象你有类似

的东西
interface Item {
 void use();
}

class Berry implements Item{
  @Override
  public void use(){
     //eating a a barry
  }
}

class EmptyItem implements Item{
  @Override
  public void use(){
     //do nothing
  }
}

然后你将在use

里面的方法中实现逻辑
item.use();

我建议您将库存创建为更复杂的对象而不是数组(复杂对象可以使用数组自行组合)

想象一下,可以通过这种方式创建库存(将其大小作为参数传递):

class Inventory{

    private Item[] items;

    public Inventory(int size){
        items = new Item[size];
        // references are null by default, just making this explicit for op
        for(int i = 0; i<size; i++){
           items[i] = null;
        }
    }

    public void addItem(int space, Item item){
       // check for input params
       // check array boundaries
       // check for item in the selected space
       if(items[space] == null){
           items[space] = item;
       }else{
          // space not empty!
       }
    }

    // I'd like more the approach of using get item -> item.use() :)
    // but this is a bit more inline with op approach
    public void useItem(int space){
       // check array boundaries
       Item item = items[space];
       if(item != null){
           item.use();
       }
    }    

    // keeping the null management inside the class itself
    public Item getItem(int space){
       // check array boundaries           
       Item item = items[space];
       if(item == null){
         item = new EmptyItem();
       }
       return item;
    }     
}

想象一下你的建模是什么样的现实生活对象,想象它们如何互相影响,并尝试相应地模拟它们的属性和行为:)

答案 1 :(得分:1)

if else树的替代方法是switch语句。

switch(items[place]) {
    case 0:
        return false;
    case 1:
        items[place] = 0;
        return true;
    case 2:
        items[place] = 1;
        return true;
    default:
        return false;
}

<强> DEMO

答案 2 :(得分:1)

我会说为项目使用自定义类,例如:

class InventoryItems {
    private HashMap<Integer, Integer> items = new HashMap<Integer, Integer>();

    public InventoryItems(final HashMap<Integer, Integer> items) {
        this.items = items;
    }

    public boolean hasItem(final Integer index) {
        return items.containsKey(index) && items.get(index) > 0;
    }

    public boolean useItem(final Integer index) {
        if (!hasItem(index)) {
            return false;
        }

        items.put(index, 0);
        return true; 
    }
}

你正在做的事情并没有错,只是从长远来看,这真的很难实现。这会将所有域模型逻辑泄露到外部,因此您需要维护复杂的功能代码,并在任何时间点知道应用程序的状态。

虽然出于测试和学习目的,我认为其他人建议对列表中的所有可能项目使用switchif检查。

答案 3 :(得分:0)

这可以由switch案件处理。这看起来像这样:

public boolean useItem(int place){
    //out of array request?
    if (place > items.length) return false;
    switch (items[place) {
        case 0: //empty
        default:
        return false;
        case 1: //eat berrys
            items[place] = 0;
        return true;
        case 2: //shoot arrow
            items[place] = 0
        return true;
    }
    //item not there
    return false;
}