在 Java 中创建 API 库的方法是什么

What is the way to create API Library in Java

我正在创建一个 API 检查函数列表。有一个对象作为要检查的参数传入。

对象如下:

public class People{

    private String name;
    private String address;
    private int age;
    private String job;

    public getter() ...
    public setter() ...

}

我创建了一个 class,其中包含一个检查功能列表,以确保提供的信息有效或无效。例如:

public class checkingFunctions {

public static boolean checkName(People ppl){

     perform the name checking function;

}

public static boolean checkAge(People ppl){

     perform the age checking function;

}

}

我知道上面的方法作为 API 工作,以便其他人可以调用 checkingFunctions.checkName(ppl)。但这是构建将作为 jar 文件公开给其他人的 API 的正确方法吗?我正在考虑创建一个如下所示的 checkingFunctions 接口:

   public interface ICheckingFunctions {

        boolean checkName(People);

        boolean checkAge(People);

}

并让 checkingFunctions class 来实现它,比如

public class checkingFunctions implements ICheckingFunctions {

}

但是它不会编译,因为如果覆盖 superclass 方法,则不能将 checkName 和 checkAge 声明为静态。

或者我应该只使用接口并让它实现接口,但从所有检查方法中删除静态。那么,如果其他人想使用我的 API,他们只是实例化接口,然后使用 instance.checkName() 来调用方法?那是个好方法吗?

我想知道是否存在行业标准或设计模式标准来创建这样的接口以便其他人可以调用它。

非常感谢。

如何设计这样的 API 很大程度上取决于您的 API 的用途。

例如,如果事实证明,您的 People class 最好作为最终 class 实施,并且您想确保它始终是 checked 以同样一致的方式,然后提供一些 public 静态 check... 方法当然是一个合理的方法。

另一方面,如果您事先不知道应该如何检查您的 People class,那么我会考虑提供一个 ICheckingFunctions 接口来声明必要的 check... 方法。但是如果你走这条路,你可能还需要为用户提供一种方法来更改 ICheckingFunctions.

的实际使用的实现。

您还应该考虑,虽然使用接口肯定更加灵活和可扩展,但维护工作也更多,并且还可能带来安全风险 - 例如如果您允许用户更改使用的 ICheckingFunction,那么您将无法再控制 People class 的检查方式。

使用界面实现这种 API 的一种可能方法是允许用户 register/unregister 在您的 class 中使用 ICheckingFunction非常幼稚 的实现可能如下所示:

public final class CheckingFunctions {
    private static ICheckingFunctions checkFunction;

    public static void registerCheckFunction(ICheckingFunctions checkFunction) {
        CheckingFunctions.checkFunction = checkFunction;
    }

    public static boolean checkName(People ppl){
        return checkFunction.checkName(ppl);
    }

    public static boolean checkAge(People ppl){
        return checkFunction.checkAge(ppl);
    }
}

这当然只是一个最小的例子。在实际的 API 中,您将不得不决定很多额外的细节。例如:

  • 是否只有一个 ICheckingFunctions 实例可用?如果可能有更多的注册ICheckingFunctions - 你如何选择使用其中的哪些功能?
  • 谁可以 register/unregister ICheckingFunctions 实例?
  • 可以从不同线程调用 ICheckingFunctions 吗?
  • 等等

您还必须考虑您的 API 将在何种环境下使用。例如,如果你想支持在 OSGI 环境中使用你的 API,那么你可以将您的 ICheckingFunctions 作为 OSGI 服务提供。

最后但同样重要的是,我会考虑以下几点:您的用户是否可以 class People class?如果是,那么使 ICheckingFunctions 接口通用并允许注册不同 classes 的实现可能是个好主意。这里又是这种方法的一个非常天真的例子:

public final class CheckingFunctions {
    public interface ICheckingFunctions<T extends People> {
        boolean checkName(T p);    
        boolean checkAge(T p);
    }

    private static Map<Class<?>,ICheckingFunctions<?>> checkFunctions = new ConcurrentHashMap<>();

    public static <T extends People> void registerCheckFunction(ICheckingFunctions<T> checkFunction, Class<T> c) {
        checkFunctions.put(c, checkFunction);
    }

    private static <T extends People> ICheckingFunctions<T> getRegisteredCheckFunction(Class<T> c){
        ICheckingFunctions<T> checkFunction = (ICheckingFunctions<T>) checkFunctions.get(c);
        if (checkFunction == null) {
            // provide some reasonable default?
            throw new IllegalStateException();
        }
        return checkFunction;
    }

    public static <T extends People> boolean checkName(T ppl, Class<T> c){
        return getRegisteredCheckFunction(c).checkName(ppl);
    }

    public static <T extends People> boolean checkAge(T ppl, Class<T> c){
        return getRegisteredCheckFunction(c).checkAge(ppl);
    }
}