How do you write code whose logic is protected against future additional enumerations?

后端 未结 10 1553
旧巷少年郎
旧巷少年郎 2021-02-05 08:01

I\'m having a hard time describing this problem. Maybe that\'s why I\'m having a hard time finding a good solution (the words just aren\'t cooperating). Let me explain via cod

10条回答
  •  孤城傲影
    2021-02-05 08:50

    A lot of people have good suggestions, but let me add one other that doesn't require a complete redesign of code or the support of objects/classes in places (like sql) that obviously have no support for such things.

    You stated:

    Fruit fruit = acquireFruit();
    if (fruit != Fruit.Orange && fruit != Fruit.Banana)
        coreFruit();
    else
        pealFruit();
    eatFruit();
    

    Which will absolutely break in unexpected ways if Grapes are introduced. I think a better approach would be:

    Fruit fruit = acquireFruit();
    Boolean fruitPrepared = false;
    
    if (fruit == Fruit.Orange || fruit == Fruit.Banana) {
        pealFruit();
        fruitPrepared = true;
    }
    
    if (fruit == Fruit.Apple) {
        coreFruit();
        fruitPrepared = true;
    }
    
    if (!fruitPrepared) 
      throw new exception();
    
    eatFruit();
    

    A third approach is very similar:

    Fruit fruit = acquireFruit();
    
    switch(fruit) {
      case Fruit.Orange:
      case Fruit.Banana:
        pealFruit();
        break;    
      case Fruit.Apple:
        coreFruit();
        break;
      default:
        throw new exception('unknown fruit detected');
        break;
    }
    

    Each of the above breaks in well defined ways when you've gone outside of what you've explicitly coded for. The main thing to take away is that you are explicitly doing something for a known condition as opposed to defaulting to something on an unknown condition. There's probably a better way of phrasing that.

提交回复
热议问题