Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 作用于数组的函数的API设计_Java_Api Design - Fatal编程技术网

Java 作用于数组的函数的API设计

Java 作用于数组的函数的API设计,java,api-design,Java,Api Design,我正在用Java设计一个API,用于一组作用于double数组的数值算法(用于实时金融统计)。出于性能原因,API必须与基元数组一起工作,因此不能选择List之类的 典型的用例可能是一个算法对象,它接受两个输入数组,并返回一个输出数组,其中包含从两个输入计算的结果 我想就如何在API中使用数组参数建立一致的约定,特别是: 我是否应该在所有函数中包含偏移量,以便用户可以对较大数组的部分进行操作,例如someFunction(double[]输入,int-inputOffset,int-lengt

我正在用Java设计一个API,用于一组作用于double数组的数值算法(用于实时金融统计)。出于性能原因,API必须与基元数组一起工作,因此不能选择
List
之类的

典型的用例可能是一个算法对象,它接受两个输入数组,并返回一个输出数组,其中包含从两个输入计算的结果

我想就如何在API中使用数组参数建立一致的约定,特别是:

  • 我是否应该在所有函数中包含偏移量,以便用户可以对较大数组的部分进行操作,例如
    someFunction(double[]输入,int-inputOffset,int-length)
  • 如果一个函数同时需要输入和输出参数,那么在参数列表中输入或输出应该排在第一位吗
  • 调用者应该分配一个输出数组并将其作为参数传递(这可能会被重用),还是函数应该在每次调用时创建并返回一个输出数组
目标是在效率、API用户的简单性以及API内部和既定惯例的一致性之间实现平衡

显然有很多选择,那么什么是最好的整体API设计呢

  • 如果这样做,也提供一个默认选项(从0开始,全长)
  • 我想大多数用户都会期望第二个输出。然而,如果您可以使用varargs,这可能会改变您的想法
  • 我喜欢调用方传入输出数组,但带有null选项,这意味着该方法将进行分配
  • 在详细说明vararg注释时,假设您有一个添加两个数组的方法。如果将输出数组arg作为第一个arg,并将两个输入数组放在最后,那么扩展该方法以添加N个数组是很简单的


    详细说明#3,让调用者通过输出数组,有时效率更高。而且,即使增益可以忽略不计,处理基本数组的用户可能来自C或FORTRAN背景,他们认为增益会很大,如果您不允许他们“高效”,他们会抱怨:-)

    假设您使用的数组足够小,可以在堆栈或Eden中分配,分配速度非常快。因此,让函数分配它们自己的数组来返回结果是无害的。这样做对于可读性来说是一个巨大的胜利

    我建议您开始让函数在整个数组上运行,并引入一个选项,仅当您发现数组的一部分有用时,才使用它调用函数。

    我将使用
    List
    ,并让这些方法将输出作为新的
    List
    返回:

    public List<Double> someFunction(List<Double> input)
    
    公共列表函数(列表输入)
    
    这听起来像是三个问题,下面是我的观点

    当然,这是非常主观的-因此-您的里程可能会有所不同:

  • 对。始终包括偏移和长度。如果某个特定函数的大多数用例没有 如果需要这些参数,请重载函数,以便不需要输入和长度

  • 为此,我将遵循
    arraycopy
    使用的标准:

    arraycopy(对象src、int-srcPos、对象dest、int-destPos、int-length)

  • 除非调用方反复调用您的实用程序函数,否则这里的性能差异将可以忽略不计。如果它们只是一次性的东西,应该没有区别。如果重复调用它们,则应该让调用者向您发送分配的数组


  • 公开多个函数的API设计的主要问题是其内部一致性。其他一切都是遥不可及的

    是否传递索引/长度对的决定取决于API的预期使用方式。如果希望用户编写一系列方法调用,将数据放入同一数组的不同段中,如在
    System.arrayCopy
    中,则需要索引/长度对。否则,这就太过分了

    输入优先或输出优先是您的决定,但一旦您做出决定,在所有具有类似签名的方法中都要坚持


    只有当缓冲区在客户机中得到重用时,传递输出缓冲区才是合理的选择。否则,在构建和维护一组额外的API方法时就浪费了精力。当然,这个决定与您选择使用索引/长度对密切相关:如果您选择索引和长度,您还应该选择输出缓冲区。

    我认为API设计在很大程度上是主观的,并且/或者应该受到API“用例”的严重影响。另一方面,API的用例完全取决于客户机代码

    说到这里,就我个人而言,我将利用方法重载并采用以下结构:

    具有所有参数的方法:

    void someFunction(int[]input1,int[]input2,int offset,int length,int[]output)

    这是主要功能。所有其他函数只需使用适当的参数调用它

    int[]someFunction(int[]input1,int[]input2,int偏移量,int长度)

    这将调用第一个函数,但代表调用者分配并返回输出数组

    void someFunction(int[]input1,int[]input2,int[]output)

    int[]someFunction(int[]input1,int[]input2)

    请注意,一般策略是通过删除“可选”参数来缩短参数列表


    通常,我倾向于避免根据参数(如输出数组)是否为
    null
    来更改方法行为。这样做会使捕捉细微错误变得更加困难。因此,我倾向于使用两种不同的调用样式,一种是提供输出参数(并且是必需的),另一种是方法返回其输出。

    一般来说,这是一个很好的建议,但在我的情况下并不可行——对于performa