假设我们有一个允许导入和导出分析文件的分析应用程序 (AppX(。我们希望在其中构建一些功能,以允许在企业协作平台中共享这些文件,但是我们使用2个不同的平台,例如Jive和Workplace。
虽然这有点主观,但我正在寻找这个模型是否与 OO 概念的约定相匹配?
1 - 我们在interface CollaborationService
定义了为了实现全部功能而必须实现的方法。
2 - 我们有一个abstract class DefaultCollaborationService implements CollaborationService
,其中包含某些操作的一些默认实现。
3 - 我们有一个class WorkplaceCollaborationService extends DefaultCollaborationService
和一个class JiveCollaborationService extends DefaultCollaborationService
,每个都有自己的方法,这些方法覆盖了默认抽象类中的方法。
或。。
这样更好吗:
2 -abstract class DefaultCollaborationService
- 注意,没有指向接口的链接,所以我们不必实现所有内容
3 -class WorkplaceCollaborationService implements CollaborationService extends DefaultCollaborationService
和class JiveCollaborationService implements CollaborationService extends DefaultCollaborationService
或。。
难道这一切都不对,你可以建议一个更好的方法吗?
这是在"固执己见"的边缘,所以让我们关注事实:
选项 1(使用抽象基上的接口(类应该是首选:此类的全部目的是为接口的某些方法提供实现。您会看到,当接口更改时,您可能希望编译器告诉您必须查看基类中的实现。
请记住:您不必实现所有方法 - 您仍然可以保留无法在此级别实现的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 ();
第一种方法最适合这一点。但是什么是抽象类和接口今天因默认方法而异。
如果您正在寻找面向对象的解决方案,那通常关注您的业务领域的"事物"。我对这两种建议的解决方案的主要问题是,它几乎没有反映您在第一段中描述的问题的任何内容。
那么,让我们看看你的问题域由什么组成:分析文件、Jive、Workplace,你提到">平台"是后两者的抽象。这些是第一段中提到的"事情"。
好的,那么我们需要照顾的"责任"(业务功能(是什么?你提到了">分享",所以让我们继续吧。
让我们把所有这些放在一起:
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 {
...
}
对于您提出的实际问题:
- 如果要定义通用功能,请始终使用接口
- 尽量避免"默认"或"基本"实现,即使使用接口也是如此。这不是继承的目的。也就是说,它不是用于共享代码,而是用于表达类之间的关系。