Dao注册表重构

时间:2012-01-20 16:17:57

标签: java spring

使用泛型dao模式,我定义了通用接口:

public interface GenericDao<T extends DataObject, ID extends Serializable> {
    T save(T t);
    void delete(ID id);
    T findById(ID id);
    Class<T> getPersistentClass();
}

然后,我使用以下构造函数实现了一个默认的GenericDaoImpl实现来执行这些函数:

public GenericDaoImpl(Class<T> clazz) {
    this.persistentClass = clazz;
    DaoRegistry.getInstance().register(clazz, this);
}

DaoRegistry的观点是通过与之相关的类来查找Dao。这允许我扩展GenericDaoImpl并覆盖需要特殊处理的对象的方法:

DaoRegistry.getInstance().getDao(someClass.getClass()).save(someClass);

虽然它有效但有一些我不喜欢的事情:

  • DaoRegistry是一个单身人士
  • 调用save的逻辑很复杂

有更好的方法吗?

修改 我不打算讨论Singleton是否是anti-pattern

2 个答案:

答案 0 :(得分:1)

首先,DaoRegistry是单身人士的问题是什么?

无论如何,你可以为你的实体设置一个抽象基类来实现像这样的保存

public T save(){
    DaoRegistry.getInstance().getDao(this.getClass()).save(this);
}

然后你可以简单地拨打someEntity.save()

如果实体类本身实现了整个GenericDao接口(保存,删除和查找方法),那么它可能会更直接,因此GenericDaoImpl的内容将位于您的基类中实体。

答案 1 :(得分:0)

最好使用DaoRegistry实例而不是静态方法。这将使其更易于管理测试配置。您可以将其实现为

@Component("daoRegistry")
public class DaoRegistry {
  @Autowired
  private List<GenericDao> customDaos;

  private GenericDao defaultDao = new GenericDaoImpl();

  public <T> T getDao(Class<T> clazz) {
    // search customDaos for matching clazz, return default dao otherwise
  }
}

您还可以为其添加save方法并相应地重命名。所有定制的daos都应该以bean的形式提供。