【问题标题】:Good practices for naming interfaces and implementations and placing them into packages命名接口和实现并将它们放入包中的良好实践
【发布时间】:2011-06-01 13:08:12
【问题描述】:

我主要谈论的是 Java 和经典的 OOP。假设我使用的是 DAO 模式。所以我创建了 CustomerDao、AccountDao 等接口。然后我会将其放入 org.example.dao 包中:

org.example.dao.CustomerDao
org.example.dao.AccountDao
...

到目前为止,这一切对我来说似乎都很好。然后我为这些接口创建实现。这里提出了我的第一个问题:如何命名它们?我见过的一种做法是使用 *Impl 后缀,如 CustomerDaoImpl。或者名称应该反映实现的性质,例如AccountDatabaseDao 还是 DatabaseBasedAccountDao?或者可能名称应该保持不变,然后包将描述这些实现的性质?如果您建议一种或另一种方式,那么这些实现应该放在哪里?一个单独的包(什么命名逻辑?)还是同一个包?

【问题讨论】:

标签: java oop coding-style


【解决方案1】:

有两个阵营:功能命名和技术命名。

喜欢的人:

org.example.customer
org.example.account

其他喜欢:

org.example.dao
org.example.service

我个人喜欢将接口和实现放在一个位置,只公开接口并按功能打包,因为包以这种方式具有更高的凝聚力。

随着大小的增加,您仍然可以将包拆分为 org.example.customer.daoorg.example.customer.serviceorg.example.customer.ui。 (从技术上讲,这与 org.example.dao.customer.daoorg.example.service.customerorg.example.ui.customer 相同,因为 Java 包没有嵌套。)

对于您的示例,我将从:

org.example.customer.CustomerDao
org.example.customer.DatabaseCustomerDao (package private)
org.example.account.AccountDao
org.example.account.DatabaseAccountDao (package private)

要使实现包私有,您需要一个工厂来创建实例。如果您使用的是 DI。 DI 框架为您实现工厂,您可以将实例注入仅依赖于接口协定的用户类中。

【讨论】:

  • 我也更喜欢将包用作功能层次结构而不是类类型。
【解决方案2】:

有些人会这样做

src
    org
        companyname
            dao
                impl

并在 impl 中拥有,例如

import org.companyname.dao.UserDao;

public class MySQLUserDAO implements UserDao;

src
    org
        companyname
            dao


import org.companyname.dao.UserDao;

public class UserDaoImpl implements UserDao;

我喜欢第一个选项的原因是您浏览impl 文件夹以放置接口的DAO 实现。它更整洁。

【讨论】:

    【解决方案3】:

    我不确定这方面是否有既定的最佳做法。通常我们根据实现方式使用子包。

    例如:接口可能是com.company.product.dao.ExampleDAO,并且(如果我们使用MyBATIS)实现将在:com.company.product.dao.mybatis.ExampleDAOMyBatis

    我不知道这是否是最好的方法,但我认为这里的一致性比“最好”的方法更重要 - 即无论您选择哪种方案,请确保您在整个代码库中坚持它。

    【讨论】:

      【解决方案4】:

      这完全取决于你。

      您列出的所有内容都是解决您的问题的可行解决方案,您不会是第一个这样做的人。

      也就是说,我更喜欢将类的命名作为最大的描述符:

      public interface AccountDao {}
      
      public class MySqlAccountDao implements AccountDao {}
      

      我会将两者都放在org.company.dao

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-06-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-26
        相关资源
        最近更新 更多