优雅的方式来替换多个如果政治家引发异常

时间:2019-02-11 11:32:18

标签: java if-statement exception reformat

我的应用程序提供一项服务,其中3种方法执行一些验证,并根据返回的结果引发不同的异常。

  if (!check1stCondition() {
    throw new ValidationException(message1);
  }

  if (!check2ndCondition)
    throw new ValidationException(message2);

  if (!check3rdCondition)
    throw new ValidationException(message3);
}

我如何重新格式化此代码以便将来可以维护?将来可能会进行新的检查。

4 个答案:

答案 0 :(得分:4)

您可以定义接口Checker,该接口提供一种方法check来引发异常。您的代码可以更改为类似的

public interface Checker {
    void check() throws ValidationException;
}

public class YourClass {
   private List<Checker> checkers; // initialize through (dependency inhecjetd?) constructor parameter or by simply enumerating checker in the constructor; I personally prefer the first way

   public void yourMethod() {
     for(Checkech checker : checkers) {
        checker.check();
     }
   }
}

您显然可以向check方法中添加参数,以提供待验证的数据...

已更新

如果您确实可以控制条件检查的实现,则可以切换到类似这样的方式(请参阅@Alberto Venturini的评论):

public interface Checker {
    boolean check();

    String message();
}

public class YourClass {
   private List<Checker> checkers; // initialize through (dependency inhecjetd?) constructor parameter or by simply enumerating checker in the constructor; I personally prefer the first way

   public void yourMethod() {
     for(Checkech checker : checkers) {
        if(!checker.check()) {
            throw new ValidationException(checker.message());
        }        
     }
   }
}

您可以使用Checker变量使用第一个Map<String, Checker>定义来实现类似的解决方案,该变量保持检查条件和相应的错误消息之间的关联,但是我绝对喜欢@Alberto Venturini提出的策略化方法。

我希望这种方法可以帮助您将代码移向更开放,更封闭的解决方案!

答案 1 :(得分:0)

我看到您有3种不同的情况以及3条不同的消息。 值得使用Guava preconditions之类的东西或自己编写。

您的代码会喜欢

checkState(check1stCondition(), message1);
checkState(check2stCondition(), message2);

您不会完全减少if's。但是至少可以提高可读性。

答案 2 :(得分:0)

您可以尝试使用多态性来减少if语句并提高可维护性。

只需使用这样的界面

public interface Example {

void check() throws ValidationException;
}

并实现不同的行为。

答案 3 :(得分:0)

有一种接近OOP的方法。注意:我并不坚持这样做,只是显示一个替代方案。

首先,您可以为每个条件创建一个新类。并假设您对某些数据执行检查,它看起来像:

interface Condition {
    CustomData checkedData();
}

public class Condition1 implements Condition {
    private CustomData data;

    public Condition1(CustomData data) {
        this.data = data;
    }

    public Condition1(Condition condition) {
        this.data = condition.checkedData();
    }

    public CustomData checkedData() {
        // do condition checking here and return CustomData if it's ok
        // throw exception otherwise
    }
}

然后,您可以将每个Condition包裹在另一个包裹中:

CustomData data = new Condition1(
                      new Condition2(
                          new Condition3(YOUR_DATA))).checkedData();

现在,您将确定已检查数据并准备进一步工作。

我认为它易于维护。如果您需要进行一些新的检查,只需如上所述添加一些小类,然后将数据包装在另一个Condition中。如果要更改某些条件,则不必在通用代码中查找它。您有单独的课程。