1

基本的な汎用 CRUD DAO を実装しようとして、ちょっとしたアンチパターンに遭遇しました。

GenericDao

public interface GenericDao<T, PK extends Serializable> {

  T findOne(final PK id);

  List<T> findAll();

  PK create(final T entity);

  void update(final T entity);

  void delete(final T entity);

  void deleteById(final PK id);

}

GenericDaoHibernateImpl

public abstract class GenericDaoHibernateImpl<T, PK extends Serializable> implements    GenericDao<T, PK> {

  @Autowired
  private SessionFactory sessionFactory;
  private Class<T> clazz;

  public GenericDaoHibernateImpl(Class<T> clazzToSet) {
      this.clazz = clazzToSet;
  }

  protected final Session getCurrentSession() {
    return sessionFactory.getCurrentSession();
  }

  @Override
  public T findOne(PK id) {
    return (T) getCurrentSession().get(clazz, id);
  }

  @Override
  public List<T> findAll() {
    return getCurrentSession().createQuery("from " + clazz.getName()).list();
  }

  @Override
  public PK create(T entity) {
    return (PK) getCurrentSession().save(entity);
  }

  @Override
  public void update(T entity) {
    getCurrentSession().update(entity);
  }

  @Override
  public void delete(T entity) {
    getCurrentSession().delete(entity);
  }

  @Override
  public void deleteById(PK id) {
    final T entity = findOne(id);
    delete(entity);
  }
}

顧客ダオ

public interface CustomerDao extends GenericDao<Customer, Long> {

  public Customer findByUsername(String username);

}

CustomerDaoHibernateImpl

public class CustomerDaoHibernateImpl extends GenericDaoHibernateImpl<Customer, Long> implements CustomerDao {

  public CustomerDaoHibernateImpl() {
    super(Customer.class);
  }

  public Customer findByUsername(String username);
    Criteria criteria =  getCurrentSession().createCriteria(Customer.class);
    criteria.add(Restrictions.eq("username", username));
    return criteria.list();
  }

}

私が言及している問題は、ドメイン固有の DAO 実装では、GenericDao を 2 回満たす/実装しているようなものです。GenericDaoHibernateImpl で 1 回、次にドメインの DAO インターフェース (CustomerDao) で再度実行します。ここでは、Customer と Long を使用するように宣言で指定する必要があります。次に、CustomerDaoHibernateImpl を実装し、再び Customer と Long を宣言する必要があります。

正しい方法ではないように見えるので、私は何か間違ったことをしていますか?

ありがとう

4

2 に答える 2

0

共通の祖先を拡張/実装するためのインターフェースと抽象クラスのアンチパターンとしては見たことがありません。私にとって、顧客インターフェースは、一般的なdaoで定義されたすべての操作が必要であると言っています。抽象クラスは、ジェネリックdaoを実装していると言っています。次に、顧客dao implに到達したら、顧客インターフェースを実装し、抽象クラスを拡張することによってそれを実現することを選択したことを示します。これにより、ジェネリックdaoを拡張/実装したくないが、もう一方は拡張したい場合に、抽象クラスとカスタマーインターフェイスを別々に拡張または変更できます。それが理にかなっていることを願っています

更新:havIngでジェネリックスの質問に正確に答えて冗長に指定しなかったようですが、私の答えが、同じ祖先インターフェイスを持つインターフェイスと抽象クラスに対してある程度の信頼性を与えることを願っています

于 2012-04-18T04:29:11.903 に答える
0

これをチェックしてください http://www.ibm.com/developerworks/java/library/j-genericdao/index.html

于 2012-04-18T03:39:29.647 に答える