持久性契约设计:单个通用接口与几个专用接口

时间:2014-02-11 20:39:59

标签: java generics

我正在开发一个基础库,旨在为大型应用程序提供通用接口,该应用程序旨在支持多个DBMS(Oracle,SQLServer,MySQL,PostgreSQL等)。另外,具体类可以使用JDBC或JPA与DBMS进行交互。

我想提供一个涉及域(模型)类的基本持久化操作的合同,所以我使用泛型创建了这个接口:

public interface IDomainDAO<T> {

    public int insert(T domainObject);

    public int update(T domainObject);

    public int delete(T domainObject);

    public List<T> getList(IQueryFilter queryFilter);
}

注意:IQueryFilter与我的问题无关。

我正在尝试决定是否应该提供更专业的接口,以便具体的类可以实现那些而不是IDomainDAO,或者这样做只是浪费时间。例如:

public interface IUserDAO extends IDomainDAO<User>{}

这是具体实现的示例:

public class UserDAOJDBC implements IUserDAO {

    public int insert(User domainObject){...};

    public int update(User domainObject){...};

    public int delete(User domainObject){...};

    public List<User> getList(IQueryFilter queryFilter){...};
}

另一方面,实现可以简单地如下所示(并且我不必花费一些时间提供专门的接口):

public class UserDAOJDBC implements IDomainDAO<User> {

    public int insert(User domainObject){...};

    public int update(User domainObject){...};

    public int delete(User domainObject){...};

    public List<User> getList(IQueryFilter queryFilter){...};
}

2 个答案:

答案 0 :(得分:2)

这归结为设计问题。这取决于您是否认为您将在任何时候向IUserDAO接口中不属于IDomainDAO接口的IUserDAO接口添加任何内容。

如果您考虑创建implements IUserDAO仅仅是为了让implements IDomainDAO<User>作为IUserDAO的缩写,那么它就没用了,实际上对于额外的界面更加冗长。

如果您将IDomainDAO<User>视为IUserDAO的专用形式,请保留界面;这样就可以在IDomainDAO<User>中添加不存在的功能{ - 1}},而不应该在List<User> getActiveUserList()中添加功能,例如{{1}}。

等方法

答案 1 :(得分:0)

我建议避免使用任何DAO并使用普通的Command设计模式。如果您使用JPA,那么您不需要担心JDBC,因为它支持任何类型的本机查询,JPA足够聪明,可以通过本机查询更新后避免JPA查询中的陈旧对象。 JPA查询API已经是Command设计模式,但您可以定义包装器命令以隐藏EntityManager API以方便起见,它还可以帮助稍后升级到更新的JPA版本。 命令可以帮助划分事务并重用查询结果处理代码。

如果它没有说服你并且你决定使用DAO那么你可以使用Spring DAO包装器,它们可能对事务有用,但命令设计模式有助于避免它。

您可以在此答案DAO implementations

中找到DAO框架实施的链接