美文网首页
方法和结构体的设计

方法和结构体的设计

作者: 李军_6eaa | 来源:发表于2018-02-17 10:57 被阅读0次
    check 输入参数的有效性
    • index values 必须是非负的,object references 必须是 non-null,可以使用 Objects.requireNonNull
    • 在方法体的开始处 check 输入参数的有效性,这样便于快速失败,并抛出合适的exception
    必要时进行防御性的 copies
    • Date 类过时了,不应该在新代码中使用;可以考虑使用 Instant 或者
      Local-DateTime 或者 ZonedDateTime
    如何设计好的 method signatures(方法签名)
    • 遵守命名规则
    • 避免过长的方法名
    • 避免过长的参数列表
    • 方法的类型优先使用接口,而不是具体类
    • 相对于boolean参数,优先使用two-element enum 类型
    有哪些方法可以避免过长的参数列表
    • 拆分成多个子方法
    • 创建一个包含这些参数的help类
    • 采用Builder模式
    使用overloading时,要谨慎
    • overloaded 方法是在编译期确定的,overridden 方法是在运行期确定的
    • 不要导出具有相同参数个数的两个overloadings方法,尤其是通过casts可以互相转换的参数
    List接口中的两个overloadings的remove方法:
    remove(E) 和 remove(int)。
    由于generics 和 autoboxing 的加入,这两个方法很容易使人迷惑
    
    • 相对于overloading方法,你总可以命名不同的方法名字,可以参考ObjectOutputStream中的write和ObjectInputStream中的read方法
    • 构造函数只能被overloaded,不能被overridden
    • overload方法时,不要在相同的参数位置上使用不同的functional interfaces,不同的functional interfaces 在根本上有可能是相同的
    在使用可变长度参数方法(varargs methods)时,要谨慎
    • varargs 是指接受零个或多个具体类型的参数
    • varargs 的原理是:首先创建一个size等于传入参数的个数的数组,然后把传入参数的value放入该数组,最后把该数组传入该方法
    • 从varargs的原理可知,在要求高性能的情景下,应该少用varargs
    一个方法应该返回 empty collections or arrays, 而不是 nulls
    • 下面的几个小例子
    //Returns null to indicate an empty collection. Don't do this
    private final List<Cheese> cheesesInStock = ...;
    public List<Cheese> getCheeses() {
        return cheesesInStock.isEmpty() ? null
            : new ArrayList<>(cheesesInStock);
    }
    
    //The right way to return a possibly empty collection
    public List<Cheese> getCheeses() {
        return new ArrayList<>(cheesesInStock);
    }
    
    //The right way to return a possibly empty array
    public Cheese[] getCheeses() {
        return cheesesInStock.toArray(new Cheese[0]);
    }
    
    • 为了避免空collections或arrays的重复创建,可以使用Collections.emptyList,Collections.emptySet,Collections.emptyMap等进行优化
    // Optimization - avoids allocating empty collections
    public List<Cheese> getCheeses() {
        return cheesesInStock.isEmpty() ? Collections.emptyList()
            : new ArrayList<>(cheesesInStock);
    }
    
    // Optimization - avoids allocating empty arrays
    private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];
    
    public Cheese[] getCheeses() {
        return cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);
    }
    
    一个方法返回optionals时,要谨慎
    • 容器类型,包括 collections, maps, streams, arrays, and optionals,不应该包裹在optionals里
    • Optional应该仅仅用在:you should declare a method to return Optional<T> if it might not be able to return a result and clients will have to perform special processing if no result is returned
    • 你不应该返回包装原始类型(int, long, double)的Optional,应该使用相应的 OptionalInt, OptionalLong, OptionalDouble
    • 你不应该用optional作为map的key, value, 以及 collection和array中的元素
    • 由于optional本质上是object的分配和创建,读取optional的value也有性能损失,因为在要求高性能的地方,不适合使用optional
    如果一个方法不能返回一个value,有哪些处理方法?
    • throw an exception
    • return null
    • return Optional<T>
    对于所有exposed API elements, 写doc comments
    • 小例子
    /**
     * Returns the element at the specified position in this list.
     *
     * <p>This method is <i>not</i> guaranteed to run in constant
     * time. In some implementations it may run in time proportional
     * to the element position.
     *
     * @param  index index of element to return; must be
     *         non-negative and less than the size of this list
     * @return the element at the specified position in this list
     * @throws IndexOutOfBoundsException if the index is out of range
     *         ({@code index < 0 || index >= this.size()})
     */
    E get(int index);
    
    • documentation comments 是 document your API 的最好最有效的方式

    相关文章

      网友评论

          本文标题:方法和结构体的设计

          本文链接:https://www.haomeiwen.com/subject/yuumtftx.html