【发布时间】:2015-05-13 22:33:01
【问题描述】:
这些天我正在阅读 Code Complete 这本书,并且我已经通过了有关耦合级别(简单数据参数、简单对象、对象参数和语义耦合)的部分。语义是“最差”的一种:
最隐蔽的耦合发生在一个模块 不使用另一个模块的一些句法元素,而是使用一些语义 了解另一个模块的内部工作原理。
书中的示例通常会导致运行时失败,并且是典型的糟糕代码,但今天我遇到了一种情况,我真的不知道如何处理。
首先我有一个类,我们称它为Provider 获取一些数据并返回Foo 的List。
class Provider
{
public List<Foo> getFoos()
{
ArrayList<Foo> foos = createFoos();//some processing here where I create the objects
return foos;
}
}
一个消费类执行一个算法,处理Foo's,根据一些属性合并或删除List,这并不重要。该算法使用列表的头部完成所有处理。所以有很多操作读取/删除/添加到头部。
(我刚刚意识到我可以让算法看起来像合并排序,递归地在数组的一半上调用它,但这并不能回答我的问题 :))
我注意到我返回了一个ArrayList,所以我将提供类的getFoos 方法更改为返回一个LinkedList。 ArrayList 具有 O(n) 复杂度和头部移除,而 LinkedList 具有恒定复杂度。但后来让我感到震惊的是,我可能会产生语义依赖。该代码当然可以与List 的两种实现一起使用,没有副作用,但性能也会降低。而且我编写了这两个类,以便我可以轻松理解,但是如果一个同事必须实现该算法,或者如果他使用Provider 作为另一个有利于随机访问的算法的源,该怎么办。如果他不关心内部结构,就像他不应该那样,我会搞砸他的算法性能。
声明返回LinkedList的方法也是可以的,但是“程序到接口”的原理呢?
有什么办法可以处理这种情况,还是我的设计存在根本缺陷?
【问题讨论】:
-
老实说——这不是一个糟糕的设计;
LinkedList只是一个糟糕的List。我见过的大多数代码都假设它正在处理RandomAccessList,这并不是一个不合理的假设。 -
同意@LouisWasserman - 几乎不应该使用LinkedList。您可以将所有 LinkedList 替换为 ArrayDeque。
标签: java algorithm oop design-patterns