【问题标题】:In Java, what do you call this pattern/idiom?在 Java 中,您如何称呼这种模式/习语?
【发布时间】:2019-02-07 21:25:24
【问题描述】:

我的 Java 库提供了一个接口 SomethingClient 和一个实现类 SomethingClientImpl。如您所料,该接口包含将由应用调用的方法。

但是有一个“镜像”接口SomethingHandler,其中包含应用程序提供的方法——应用程序回调。您可以想象应用程序向库提供了此接口的一个对象 - 可能提供给从中获取 SomethingClient 的 Factory 方法。

作为一个没有经验的 Java 设计者,我很想知道是否有一个名称,以及是否/在多大程度上推荐,还提供一个结合了这两个概念的接口和类:

public interface SomethingClient { /*..*/ }

public interface SomethingHandler { /*..*/ }

public interface ClientAndHandler extends SomethingClient, 
                                          SomethingHandler { }

public abstract class ClientAndHandler_Impl implements ClientAndHandler {

    final SomethingClient clientImpl_;

    ClientAndHandler_Impl(SomethingClient clientImpl) {
        this.clientImpl_ = clientImpl;
    }

    // TODO now all SomethingClient methods are implemented in terms of clientImpl_
    // AND, SomethingHandler methods are left abstract so they are implemented by the application
}

意图是,应用程序编写者可能更喜欢从 ClientAndHandler_Impl 抽象类扩展并实现回调方法,可能是在客户端(传出)方法方面。这可以相对容易地完成。假设你会这样做,你会给 ClientAndHandler 概念起什么名字?

【问题讨论】:

  • 我不知道我会怎么称呼它,但我认为ClientAndHandler 是多余的; ClientAndHandler_Impl 可以同时实现SomethingClientSomethingHandler
  • 不确定我是否正确理解了构造,但我会通过将包含的实现对象称为“委托”模式来调用 SomethingClient 的实现。
  • @daniu 这很有用,基本上,目的是将Client 部分委托给某个实现,其余部分保留抽象。
  • 为什么有SomethingHandler接口,而不仅仅是ClientAndHandler extends SomethingClient?你有只需要 SomethingHandler 方法的类吗?
  • @DevinH。也许将它们分开作为经验法则更为正统,例如,为了更容易模拟,您希望将 Handler 分开。再说一次,我可以用MockitoCALLS_REAL_METHODS 模拟abstract ClientAndHandler,这将保留具体(客户端)部分并只模拟抽象部分,但作者建议不要这样做。我正在研究更喜欢哪种方法,一方面分离更“SRP”,但也必须处理一个概念而不是 2 是初学者友好的。

标签: java oop design-patterns interface


【解决方案1】:

骨架实现

您当前的代码看起来有点像骨架实现。您可以在massachusetts institute of technologydzon 上阅读更多相关信息。

其背后的想法是为客户端提供默认实现。您可以在 Java-Collections-API 中找到一些示例,例如 AbstractCollectionAbstractSetAbstractMap

一些建议

冗余接口

接口ClientAndHandler 是多余的。 ClientAndHandler_Impl 类应该实现 SomethingClientSomethingHandler

命名

如果您想明确说明您使用的是骨架实现,我会将抽象类 ClientAndHandler_Impl 命名为 AbstractClientInteractionClientInteractionSkeleton

【讨论】:

  • 确实它看起来有点像,但骨架不包含传入/传出方法的概念,我还没有看到任何可以区分这些的概念指导(我没有t 意味着在 SO 答案中,但通常)
【解决方案2】:

首先,这不是一种设计模式。它确实包含一个:delegation pattern

至于组合接口,我可以称之为“复合marker interface”之类的。我不知道有任何公认的名称。

这很糟糕有几个原因。首先,我的类可以分别实现 A 和 B 但如果它不实现 AAndB 那么它就不会匹配这些方法的类型。因此,一般类型的交集是可取的。

其次,我认为首先需要复合类型表明设计不佳。班级应该做一件事。如果您要实现两个不同的接口,那么根据定义,您就不会做一件事。

【讨论】:

  • 从务实的角度来说,“一件事”的哲学只能走到这一步。如果在一个系统中,你有一个班级来完成 2000 件需要做的事情,那么,想象一下结果
  • @haelix 我很困惑。听起来你同意我的观点(“一个班级不应该做 2000 件事情”),但你的措辞好像你不同意我的观点。
  • 我在想,如果完全遵守“一件事”原则,最终可能会得到大量抽象,而这些抽象本身会使系统难以理解
  • @haelix 如果你需要做 2000 件事,你需要做 2000 件事。将这 2000 项内容转储到一个文件中并不会增加可维护性,反而会减少。
  • 你给出了一个稻草人的论点 - 将这 2000 件东西转储到一个文件中。我没有提出一个文件,而是根据我最初的问题,偶尔将 2 个概念融合为一个,以便更简单地向 API 用户展示。您的 API 确实需要 2000 个抽象,但这并不意味着它们作为 2000 个单独的部分向 API 用户公开。我不认为我们根本不同意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-29
  • 1970-01-01
  • 2022-08-18
  • 1970-01-01
  • 2023-03-20
  • 2014-06-12
相关资源
最近更新 更多