在Java中设计maven依赖项并避免抽象泄漏的最佳方法?
对不起,我的问题似乎很宽泛。我只是想澄清一些事情。我读过关于抽象泄漏的线程和其他一些文章。据我所知,抽象泄漏是指“用户”或开发人员看到函数背后的复杂过程。。。?比如隐藏复杂的汽车工程,或者隐藏可靠的TCP依赖于不可靠的IP的秘密。但是我在研究Java中的一些类,特别是List系列。我观察到的是List interface, AbstractList, ArrayList, and AbstractArrayList.
我注意到ArrayList类中有一些奇怪的东西。
首先我找到了这个
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
那么这个
public E get(int index) {
rangeCheck(index);
checkForComodification();
return ArrayList.this.elementData(offset + index);
}
它们具有相同的函数名,我认为这是重载,但它们也采用相同的参数?当我使用get时,我如何知道使用了哪个?这在OOP中合法吗
下一个注意事项是,我在列表中发现:
default void sort(Comparator<? super E> c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}
我想知道他们为什么选择在列表中添加默认值。我曾经有一个接口有一个默认契约,但有人指出它导致了抽象/内存泄漏When is it considered to be a good practice to use defaults in an interface?
最后,我在正在创建的依赖项中创建了一个“自定义”列表
class CustomList<T> extends ArrayList<T>{
//sample function: void sortInTheSmartestMagicalWayIdk();
}
这也是一个设计缺陷。“它依赖于ArrayList。如果ArrayList在将来变得过时会怎么样?那么您所建立的依赖关系也将如此。”这就是他们告诉我的。是的,这听起来不错,那么向List类添加一些自定义函数的最佳方法是什么呢?如果我想让项目中的一个实体充当列表,我是否应该创建一个扩展列表的接口,然后创建该接口的实现,并将该实现用作我的“自定义列表”
# 1 楼答案
这个问题似乎有点没有重点
1)关于两种
get
方法:一种属于ArrayList
,另一种属于private class SubList
。仔细观察缩进,您会立即发现这两种方法甚至不在同一缩进级别上2)如果该方法在大多数实现类中可能以完全相同的方式实现,则应提供默认实现。如果接口过于通用,并且不允许以合理有效的方式实现方法,则最好不要提供默认实现,以便向接口的实现者发出信号,说明此方法不是免费提供的,需要一些注意和努力
3)在
CustomList
中,您是否希望您的界面用户依赖于保证它始终是一种特殊的ArrayList
?如果是这种情况(可能性很小),那么您可以保持原样。如果不是这样,您应该去掉extends ArrayList
,用implements List
替换它,然后可能在实现中包装一个ArrayList
。如果您后来认为ArrayList
不是最好的主意,那么您可以用其他实现替换私有包装的成员变量,而不会破坏所有使用API的人的代码