2011-05-22 111 views
6

在大型软件实现中,通常建议将API设计与其实现分离。但在某个地方,它们必须重新连接(即,实施必须重新连接到API)。API和Implementation之间应该是完全分离的吗?

以下示例显示了一个API设计,并通过实例对象的执行的调用:

import java.util.List; 

public abstract class Separation { 

    public static final Separation INSTANCE = new SeparationImpl(); 

    // Defining a special list 
    public static interface MySpecialList<T> extends List<T> { 
     void specialAdd(T item); 
    } 

    // Creation of a special list 
    public abstract <T> MySpecialList<T> newSpecialList(Class<T> c); 

    // Merging of a special list 
    public abstract <T> MySpecialList<? extends T> specialMerge(
     MySpecialList<? super T> a, MySpecialList<? super T> b); 

    // Implementation of separation 
    public static class SeparationImpl extends Separation { 

     @Override 
     public <T> MySpecialList<T> newSpecialList(Class<T> c) { 
      return ...; 
     } 

     @Override 
     public <T> MySpecialList<? extends T> specialMerge(
      MySpecialList<? super T> a, MySpecialList<? super T> b) { 
      return ...; 
     } 

    } 

} 

有人会说,API应该不是指实现代码。即使我们通过单独的文件将API代码与实现分开,通常也必须在API中导入实现代码(至少是类名)。

有一些技术可以通过使用完全限定名称的字符串表示来避免这种引用。该类用该字符串加载,然后实例化。它使代码更复杂。

我的问题:从实现代码中完全分离或隔离API代码有什么好处吗?或者,这仅仅是纯粹主义者试图达到完美而没有什么实际好处的尝试?

回答

6

我一直理解要求从执行单独的接口意味着你不与什么混音实施如何。所以在上面的例子中,混合api和实现将意味着在api中公开一些特定于SeparationImpl如何实现您的API的内容。

作为一个例子,看看如何在各种集合类中实现迭代。还有更具体的方法可以检索特定集合中的元素(例如,通过在ArrayList中的位置),但这些方法不会在Collection中公开,因为它们特定于如何实现具体的ArrayList。我也看到有大量接口目录的项目,每个接口都有一个具体的实现,并且每个接口都在其具体实现中机械地复制每个方法,这看起来像一个完全没有意义的“假装”抽象,如同它实际上并不提供任何逻辑抽象。

3

OSGi中经常使用的一种技术是将API放在一个单独的模块中用于实现。 API应该自己编译,避免直接引用任何实现。

+0

这是OSGi绝对必要还是仅仅是良好的做法? – JVerstry 2011-05-22 20:03:16

+0

要使用像iPOJO这样的框架是必要的,但是你不必在所有情况下都这样做(而且我不这样做) – 2011-05-22 20:09:06

2

Peter's和Steve的答案已经足够,但我想补充更多的内容 - 如果您只有单一的接口或抽象类的实现,那么它就没有任何接口或抽象类,因为它无法实现抽象的目的。
在你的情况我真的不明白 - 为什么你实现Separation作为一个抽象类,而SeparationImpl本身可以是API类,或者如果你有不同的实现Separation可以是inetrface,如果你有一些共同的功能,那么你可以有另一个抽象类实现你的接口,然后继承这个抽象类。样本的类层次看起来像

interface Separation --> AbstractSeparation --> SeparationImpl 

就像标准的集合库

interface List --> AbstractList --> ArrayList 
+0

即使只有一个生产实现,ABCs和接口仍然是一件好事,首先,他们强化了对问题的清晰分离。其次,它们允许通过mock轻松进行单元测试。 – 2011-05-22 19:30:36

+0

我想说明一个事实,即有时需要访问API的实例,一种方法是从API本身提供它。我同意,这可能只是通过接口完成的。 – JVerstry 2011-05-22 20:06:09

+0

@Oli Charlesworth - 我们可以嘲笑具体的类,至少不需要为嘲笑目的设置接口。 – Premraj 2011-05-23 04:59:04

1

附加到好点从其他作者的我就更不用说了单元测试目的:

模拟对象的时候,如果接口不是类,就更容易。

相关问题