OO设计 - 公共API方法实现

时间:2014-08-13 02:48:57

标签: java android public

实现一个公共方法来调用另一个公共方法(类似于API)是不是一种好的做法?当API的用户重写这些方法时,我担心重复问题。我建议使用私有方法(可以通过两种原始公共方法调用)来进行实际实现。

想象一下像List一样的数据结构。如果我有一个addAll(lotsoItems)调用add(simgleItem)为每个项目,这将导致用户重写时出现问题。 他可以在他的覆盖中做一些逻辑"添加"并且在" addAll。"这个逻辑会被复制,因为他不知道我打算打电话给#34;添加"当我这样做的时候。

看起来Java(至少8个)以我描述的方式实现ArrayList。 谢天谢地,与Android的ArrayAdapter相同。

我的问题是:在设计可以扩展的API或类时,何时可以从其他公共方法调用公共方法?

编辑:有一个明显的例子:

让我们说我正在扩展ArrayList,因为我想" bark"在用户(System.out.println(" Bark!");)每次将某些内容添加到列表中。够容易吧?所以,我去覆盖.add(Object o)做.bark()然后调用.super(o)。然后我将.addAll(Object ... os)重写为.bark(),因为os数组很长,然后调用.super(os)。呃,哦,这就是问题所在:ArrayList的实现者只是在.addAll中调用了.add,而.bark的调用次数是我预期的两倍!

这是我的结论

https://gist.github.com/NightlyNexus/1256e4e36428b44ebf57

tl;博士我现在对OO设计不满意。

3 个答案:

答案 0 :(得分:1)

对于String类

怎么样?
public String substring(int beginIndex) {
  return substring(beginIndex, count);
}

public String substring(int beginIndex, int endIndex) {
....
}

答案 1 :(得分:1)

Effective Java

中讨论了与您描述的ArrayList完全相同的问题

根据我的记忆,解决方案不是因为你指出的原因而扩展ArrayList,而是将ArrayList作为你自己类的成员。

这样你也可以随时用你想要的任何东西替换ArrayList。

答案 2 :(得分:0)

为什么要在另一个公共方法中调用公共方法有很多不同的原因。

一个例子是变异者。如果在分配变量之前使用mutators来执行检查,那么即使在公共方法中,您也会发现自己在整个类中调用变量的变换器(通常是公共的)。

另一个原因是如果你有一种行为通过使用某种反向执行碘化来扩展另一种行为:

 public void eat(Food f) {
      //eat food
 }

 public void eatWithFork(Food food) {
      //set utensil to fork
      //grab knife if needed
      eat(food);
 }

(当然这不是最好的例子,因为你可能会选择基于食物实例通过的器具,而不是让方法成为决定,但它是一个扩展行为的例子

至于JDK中的用法,请查看boolean addAll(Collection)的源代码。它调用公共方法void ensureCapacity(int)