2012-04-18 1 views
1

В попытке реализовать базовый родовой CRUD DAO, я побежал в то, что кажется немного в антипаттерн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); 
    } 
} 

CustomerDao

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 дважды. Однажды в GenericDaoHibernateImpl, а затем снова в нашем доменном интерфейсе DAO, то есть CustomerDao. Здесь мы должны указать в декларации, использовать Customer и Long. Затем мы реализуем CustomerDaoHibernateImpl, и снова мы должны объявить Customer и Long.

Я делаю что-то неправильно, потому что это просто не похоже на правильный путь.

Благодаря

+0

Это один из причины, по которым я не верю в определение классов DAO с использованием интерфейсов. Одним из способов упрощения вашей модели является устранение взаимосвязи между вашими интерфейсами CustomerDAO и GenericDAO. – Perception

ответ

0

Я никогда не видел его в качестве анти-шаблон для интерфейса и абстрактного класса для расширения/реализации общего предка. Для меня интерфейс клиента говорит, что он требует всех операций, определенных в общем dao. В абстрактном классе говорится, что он реализует общее dao. Затем, когда вы дойдете до своего клиента dao impl, вы укажете, что вы реализуете интерфейс клиента, а затем решили выполнить это, расширив абстрактный класс. Это позволяет абстрактному классу и интерфейсу клиента расти или меняться отдельно, если он когда-либо хотел не расширять/реализовывать общий дао, а другой. Надеюсь, что имеет смысл

UPDATE: Я вижу, я не точно ответить на ваш вопрос дженериков на том, чтобы избыточно указать, но надеюсь, что мой ответ дает некоторое доверие к границе раздела и абстрактного класса, имеющих одинаковый интерфейс предок