Java OO 概念 - 接口和抽象的正确使用 class?

Java OO concept - correct use of interface & abstract class?

假设我们有一个允许导入和导出分析文件的分析应用程序 (AppX)。我们想在其中构建一些功能以允许在企业协作平台中共享这些文件,但是我们使用 2 个不同的平台,例如 Jive 和 Workplace。

虽然这有点主观,但我想看看这个模型是否符合 OO 概念的约定?

1 - 我们在 interface CollaborationService 中定义了必须实现的方法才能实现全部功能。

2 - 我们有一个 abstract class DefaultCollaborationService implements CollaborationService 对某些操作有一些默认实现。

3 - 我们有一个 class WorkplaceCollaborationService extends DefaultCollaborationService 和一个 class JiveCollaborationService extends DefaultCollaborationService,每个都有自己的方法,它们覆盖了默认摘要 class.

中的方法

或者..

这样更好吗:

2 - abstract class DefaultCollaborationService - 注意,接口没有 link,因此我们不必实现所有内容

3 - class WorkplaceCollaborationService implements CollaborationService extends DefaultCollaborationServiceclass JiveCollaborationService implements CollaborationService extends DefaultCollaborationService

或者..

是不是都不对,有更好的方法吗?

这是在 "opinionated" 的边缘,所以让我们关注事实:

选项 1(使用抽象基础上的接口)class 应该是首选:此 class 的全部目的是为 some[=21= 提供实现] 接口的方法。你看,当接口改变时,你 可能 想要编译器告诉你必须查看基础 class.

中的实现

请记住:您不必实现所有方法 - 您仍然可以保留那些无法在此级别实现的 abstract

除此之外,您的做法似乎是合理的。

让我们看一下整个模式,了解所需的实施和提供的服务。

class Use1 extends Base
    @Override protected onA(X x) { }
    @Override protected onB(X x) { }

class Use2 extends Base
    @Override protected onA(X x) { }
    @Override protected onB(X x) { }

abstract class Base implements Api
    abstract protected onA(X x); // Requirement
    abstract protected onB(X x);
    public final a () { onA(x); } // Service
    public final b () { onB(x); }

interface Api
    public final a ();
    public final b ();

第一种方法最适合这种情况。但是什么是抽象 class 和接口今天因默认方法而异。

如果您正在寻找面向对象的解决方案,通常会关注 "things" 您的业务领域。我对这两个提议的解决方案的主要问题是,它几乎没有反映出您在第一段中描述的任何问题。

那么,让我们看看您的问题域包括哪些内容:分析文件JiveWorkplace,你提到“Platform”作为后两者的抽象。这些是第一段中提到的"things"。

好的,那么我们需要处理的 "responsibilities"(业务功能)是什么?你提到“共享”,所以让我们开始吧。

让我们把所有这些放在一起:

public interface AnalyticFile {
    void shareTo(Platform platform);
}

public interface Platform {
    void share(byte[] data); // Whatever data is necessary
}

public final class Jive implements Platform {
    ...
}

public final class Workplace implements Platform {
    ...
}

对于您提出的实际问题:

  • 如果要定义通用功能,请始终选择接口
  • 尽量避免 "default" 或 "base" 实现,即使有接口也是如此。这不是继承的目的。也就是说,它不是为了共享代码,而是为了表达类.
  • 之间的关系