【问题标题】:How to name repository and service interfaces?如何命名存储库和服务接口?
【发布时间】:2012-03-13 02:39:42
【问题描述】:

您如何命名存储库和服务接口及其实现类?

例如,我有一个名为 Question 的模型。您将如何命名存储库(接口和实现)和服务(接口/实现)。

阅读这些帖子后: Java Interfaces/Implementation naming conventionInterface naming in Java我重新考虑了我已经做过的事情:)

【问题讨论】:

    标签: java jakarta-ee domain-driven-design naming-conventions


    【解决方案1】:

    我认为DDD中的命名大致有两种方式:

    1) 基于刻板印象。这是您在其名称中包含类构造型的地方。例如:

    QuestionsRepository, TaxCalculatingService etc
    

    2) 基于域。在这种方法中,您只使用领域语言并省略类名中的任何构造型。例如:

    Questions (or AllQuestions), TaxCalculator etc.
    

    实现类将命名为SqlQuestionsInMemoryQuestions

    我都试过了,但我现在更喜欢第二种选择,因为它似乎更符合 DDD 的心态。它似乎更具可读性并且具有更好的信噪比。以下是 Phil Calçado 在存储库上的 great article 的引用:

    作为对象列表的存储库的概念并不难理解,但这些类最终得到与列表无关的方法是很常见的。

    在指导了许多团队采用通用语言和相关模式后,我发现让人们记住存储库不是类似于 DAO 的类的最佳方法是从如何命名它们开始。

    几年前,Rodrigo Yoshima 告诉我他在命名存储库时的惯例。而不是下面显示的更常见的命名样式:

    class OrderRepository {
       List<Order> getOrdersFor(Account a){...}
    }
    

    他提倡这个:

    class AllOrders {
       List<Order> belongingTo(Account a){...}
    }
    

    这看起来是个小改动,但它有很大帮助......

    整篇文章非常值得阅读和收藏。

    【讨论】:

    • 我知道这可能是一个小细节,但实现类应该有后缀或前缀吗? SQLAllQuestions 还是 AllQuestionsSQL?你喜欢什么?
    • 我个人会使用 SqlAllQuestions,但我看不出有什么理由不使用 AllQuestionsSql,可能会更好。正如您所说,这并不重要,因为此名称只会在您的应用程序的“组合根”部分中使用,而且您不会经常看到它 (blog.ploeh.dk/2011/07/28/CompositionRoot.aspx)
    • 还有一件事。我阅读了您的链接,这很棒,但是当您拥有 AllQuestions 界面并且想要列出所有问题时,您会怎么做? AllQuestions.everything()?做 CRUD 的时候有什么约定吗?
    • Questions.All() 将是可读的。 CRUD 是一个完全不同的讨论,它来自 data,而不是 domain 世界。考虑生命周期比考虑 CRUD 更好。使用构造函数或工厂 (C) 创建的域对象。您可能还有一个方法 Questions.Add(question) 可以将对象添加到存储库(内部存储库将使用休眠来实现此方法)。生命的终结并不总是像删除一样简单...(用完 cmets 的空间)
    • "Questions" 作为 repo 名称一开始听起来不错,但它会导致复数问题。这就是 QuestionRepository 更好的原因。您可以将存储库一词替换为更自然的东西,例如 QuestionGroup,但这并不重要,恕我直言。
    【解决方案2】:

    我个人使用FooServiceFooServiceImplFooRepositoryFooRepositoryImpl

    你可能会说Impl 后缀是噪音,但是

    • 通常只有一种实现,所以没有FirstFooServiceSecondFooService
    • 具体的FooXxxImpl 类型在代码中除了在单元测试中没有使用:注入依赖项,它们的类型是接口

    【讨论】:

    • 我使用FooDao 而不是FooRepository,因为它的输入更短:)
    • 我认为不需要 FooService 接口,因为您只有一个实现。接口的目的是对可能有更多实现的对象/组件进行建模。比如validationRule,一些策略模式。我个人认为有很多界面过度使用。此外,您的实现具有 Impl 后缀这一事实告诉我,您的实现无论如何都不是特定的。实现名称应包含实现细节。例如,List、LinkedList、ArrayList。我知道这种方法很常见,但这并不意味着它很好。
    • 我不再使用接口了。请记住,这是 2012 年的答案。从那时起,框架和模拟框架就不断发展。
    猜你喜欢
    • 1970-01-01
    • 2014-09-13
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多