当前位置: 首页 > 知识库问答 >
问题:

检查默认响应时避免代码重复

邓宜年
2023-03-14

我有一个调用外部API的Java程序(RealApi在下面的代码中),有时我想避免调用此API,而是返回预先构造的响应(由FakeApi生成)。

所以,我在大多数方法中都复制了这种构造:

public Type1 m1(String s) {
    try {
        Type1 r = FakeApi.m1(s);
        if (r != null) {
            return r;
        }
    } catch (Exception e) {
        // log error
    }

    return RealApi.m1(s);
}

有哪些选项可以避免在任何地方重复这个try/catch块?重要的是,如果FakeApi抛出异常或返回null,则必须调用RealApi

共有2个答案

潘阳舒
2023-03-14

这不像Thomas Preiúler的答案那么简单,但它会帮助你根本不重复任何方法。所以如果你扩展接口,你只需要修改具体的类,而不是描述你想要的实际行为的链接器。

创建一个包含RealApi所有方法的接口:

interface Api {
  Type1 m1(String s);
}

然后是一个执行实际调用的类:

class ConcreteApi implements Api {
  public Type1 m1(String s) {
    return RealApi.m1(s);
  }
}

然后创建你的FakeApi:

class TotallyFakeApi implements Api {
  public Type1 m1(String s) {
    return FakeApi.m1(s);
  }
}

现在,要避免重蹈覆辙,需要注意的一点是:

private static Object callImplementation(Api api, Method method, Object[] methodArgs) throws Exception {
  Method actualMethod = api.getClass().getMethod(actualMethod.getName(), actualMethod.getParameterTypes());
  return actualMethod.invoke(api, methodArgs);
}
Api fakeOrReal(Api fakeApi, Api realApi) {
  return (Api) Proxy.newProxyInstance(
      FakeApi.class.getClassLoader(),
      new Class[]{Api.class},
      (proxy, method, methodArgs) -> {
        try {
          Object r = callImplementation(fakeApi, method, methodArgs);
          if (r != null) {
            return r;
          }
        } catch (Exception e) {
          // logError(e);
        }
        return callImplementation(realApi, method, methodArgs);
      }
    );
  
}

获得如下实际实现:

Api apiToUse = fakeOrReal(new TotallyFakeApi(), new ConcreteApi());
訾稳
2023-03-14

一个选项是将错误检查行为封装到自己的方法中:

public <T> T fakeOrReal(Supplier<T> fake, Supplier<T> real) {
  try {
    T r = fake.get();
    if (r != null) {
      return r;
    }
  }
  catch (Exception e) {
    // log error
  }

  return real.get();
}

然后你就可以用

public Type1 m1(String s) {
  return fakeOrReal(() -> FakeApi.m1(s), () -> RealApi.m1(s));
}
 类似资料:
  • 我想知道是否有可能在Java中“避免”空检查,以下面的代码为例: 它必须检查4次,否则代码将失败。 是否可以将语句转换为只有在没有NullPointerException时才执行的一行式语句?当出现异常时,该行应该被忽略。 这里我不是在谈论一个通用的语言特性,我是在谈论一个只有当您明确决定这样做时才会上交的特性。 例如:将是建议代码的一个片段。 在Java可能发生这样的事情吗? 如果不可能的话,在

  • 问题内容: 有什么方法可以使JAXB不保存其值是@Element批注中指定的默认值的字段,然后在从XML加载null或空值的元素时对其设置值?一个例子: 应生成: 而当加载 我正在尝试执行此操作,以生成干净的XML配置文件,并使其可读性更强且尺寸更小。 敬请谅解,谢谢。 问题答案: 您可以通过在get / set方法中使用逻辑并将逻辑放入其中来执行以下操作: 例 演示版 输出量 想要查询更多的信息

  • 问题内容: 我正在调用一些JSON并将相关数据解析为CSV。我无法弄清楚如何使用默认密钥填充中间的JSON dict文件,因为其中很多是未填充的。当我尝试将内容解析为CSV时,结果为KeyError。 我现在收到(制造商)的“ NoneType”错误: 问题答案: 您可以使用而不是直接引用键。

  • 在Java,有没有一种方法可以避免在调用的每个级别上嵌套null检查,以确保沿途没有阻止下一次调用的null。有没有一个优雅的方法来做这件事? 例如: Objone.ObjTwo.ObjTree.ObjFour.ObjF

  • 问题内容: python的新手,新手开发人员,首次调用 我正在调用一些JSON并将相关数据解析为csv。我无法弄清楚如何使用默认键填充中间的json Dict文件,因为其中很多都没有填充。当我尝试将内容解析为csv时,结果是KeyError。希望有任何建议! 谢谢。 更新:谢谢大家!我现在收到(制造商)的“ NoneType”错误: 问题答案: 您可以使用而不是直接引用键。

  • 问题内容: 我目前正在学习go,我的一些代码如下所示: 这在我看来有点不对劲,因为错误检查占用了大多数行。有没有更好的方法来进行错误处理?我是否可以通过一些重构来避免这种情况? 更新: 感谢您的所有答案。请注意,在我的示例中,doB取决于a,doC取决于b,依此类推。因此,大多数建议的重构在这种情况下不起作用。还有其他建议吗? 问题答案: 这是一个常见的投诉,有几个答案。 以下是一些常见的问题: