在Java中重写条件语句

在Java中重写条件语句,java,design-patterns,conditional,Java,Design Patterns,Conditional,假设我有下面的代码,它主要是确定一些条件是否匹配,然后分配布尔值,然后运行一些代码。如果布尔值为false,则抛出异常。如果我希望它在booleanValue为false时立即抛出异常,而不运行其余代码,该怎么办?如果我把第二个条件语句放到第一个条件语句中,就会有重复的代码。请告诉我一个聪明的方法来做到这一点(我已经修改了代码,使之看起来像我的实际代码) 而不是 booleanValue = anotherMethod(); 你只需要写 if( !someMethod() ) thro

假设我有下面的代码,它主要是确定一些条件是否匹配,然后分配布尔值,然后运行一些代码。如果布尔值为false,则抛出异常。如果我希望它在booleanValue为false时立即抛出异常,而不运行其余代码,该怎么办?如果我把第二个条件语句放到第一个条件语句中,就会有重复的代码。请告诉我一个聪明的方法来做到这一点(我已经修改了代码,使之看起来像我的实际代码)

而不是

 booleanValue = anotherMethod();
你只需要写

if( !someMethod() )
   throw new SomeException();

在抛出泛型异常时--不要。抛出异常的原因是告诉调用方发生了异常。告诉他们什么几乎总是很有用的,否则无论是打电话的人还是你都无能为力。

假设这两个
有些代码是不同的…
,你可能想做:

boolean booleanValue = someCondition ? someMethod() : anotherMethod();
if(!booleanValue) {
    throw new Exception();
}

if(someCondition) {
    // some code
} else {
    // some code
}
如果它们是相同的,
If(someCondition)
是不必要的


如果(假设)您有一个不允许三元表达式的静态分析工具,您可以将第一行替换为:

boolean booleanValue;
if(someCondition) {
    booleanValue = someMethod();
} else {
    booleanValue = anotherMethod();
}

去掉布尔变量怎么样?您可以像这样重写代码:

if (someCondition) {
   if (!someMethod()) {
     throw new Exception();
   }
   some codes...
}
else {
   if (!anotherMethod()) {
     throw new Exception();
   }
   some codes...
}
这在我看来比较容易,但这是一个品味的问题


额外的优势:如果异常最终出现在堆栈跟踪中,您就知道情况是什么,因为您有两个不同的throw语句。这可能会加快调试速度。

显而易见的解决方案是:

boolean booleanValue = false;

if (someCondition) {
   booleanValue = someMethod();
   if(booleanValue){
       //some codes...
   }
}
else {
   booleanValue = anotherMethod();
   some codes...
}

if (!booleanValue) {
   throw Exception();
}

。。。但是我不介意重复
if(!booleanValue)抛出异常()位,因为抛出异常的原因可能在概念上有所不同。(例如,您可以在异常中提供更好的错误消息。)

这可能都是非常主观的

boolean booleanValue = aBoolean;
if (someCondition) {
   if (!someMethod()) {
       throw new SomeException();
   }
   some codes...
} else {
   if (!anotherMethod()) {
     throw new AnotherException();
   }
   some other codes...
}

你最好的解决办法是

if (someCondition) {
   value = getPermission_1();

   if (!someMethod(value)) {
     throw new SomeException();
   }

   useValue_1(value);
}
else {
   value = getPermission_2();

   if (!anotherMethod(value)) {
     throw new AnotherException();
   }

   useValue_2(value);
}
你不应该把它看作是重复代码,因为如果你想抛出一个异常,那么你的期望是,在每种情况下,异常的原因是不同的,因此在每种情况下,应该传递不同的异常,或者不同的消息


我假设你想知道哪个条件被执行了,然后失败了,因为你得到的只是一个来自…方法调用的布尔值。在这个场景中失败的原因可能不会很明显。

这种气味。。。如“代码气味”。返回值正在转换为异常。似乎如果调用方编写了someMethod和anotherMethod,那么解决方案是重写这些方法,并从这些方法中抛出异常,而不是使用返回值。但是,只有当程序员有权访问代码时,才能这样做。如果是第三方API调用,我想可能必须进行转换。

这对我来说是糟糕的代码风格。将在checkStyle阶段失败。@newguy好吧,您必须定义好的代码样式是什么;我对该代码没有问题我的项目使用了一个检查样式插件,它不允许任何像第一行这样的代码,所以我必须遵守这个规则。@newguy你的项目不允许三元表达式?这似乎…糟糕,这不是解决办法。我想要的是在布尔值赋值后立即抛出异常,因为我不想运行其余的代码。@newguy:请再看一次。它就是这样做的。不过对我的口味来说有点不太清楚。我更喜欢Joel和Nils给出的答案。@newguy:这个解决方案确实满足了你的要求。就我个人而言,我不喜欢这种风格,但它可能是编辑差异最小的解决方案。如果anotherMethod()给出一个假布尔值,它仍将运行其余的代码,这不是我想要的。@newguy:你是对的,可以假设你会在第一个block语句中看到模式,并推断出解决方案。你是对的,但是我问的是一个不同的问题,这就是为什么我没有指定一个特殊的EXCEPTION名称。只是要指出,如果(!someMethod())与原始代码保持一致,那么问题就更复杂了。事实上,问题更复杂了,请查看我修改过的代码。不知道这会使问题更复杂。。。我的解决方案或@Nils或此解决方案仍适用于您的更新方案。
if (someCondition) {
   value = getPermission_1();

   if (!someMethod(value)) {
     throw new SomeException();
   }

   useValue_1(value);
}
else {
   value = getPermission_2();

   if (!anotherMethod(value)) {
     throw new AnotherException();
   }

   useValue_2(value);
}