问题
At this moment, I have two classes: UserHibernateDao
and TicketHibernateDao
:
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import model.dao.Dao;
import model.entity.User;
public class UserDaoHibernate extends HibernateDaoSupport implements Dao<User> {
public User get(long id) {
return getHibernateTemplate().get(User.class, id);
}
public void save(User user) {
getHibernateTemplate().save(user);
}
public void remove(long id) {
getHibernateTemplate().delete(
getHibernateTemplate().get(User.class, id));
}
}
and second:
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import model.dao.Dao;
import model.entity.Ticket;
public class TicketDaoHibernate extends HibernateDaoSupport implements
Dao<Ticket> {
public Ticket get(long id) {
return getHibernateTemplate().get(Ticket.class, id);
}
public void save(Ticket ticket) {
getHibernateTemplate().save(ticket);
}
public void remove(long id) {
getHibernateTemplate().delete(
getHibernateTemplate().get(Ticket.class, id));
}
public void save(Ticket ticket) {
getHibernateTemplate().saveOrUpdate(ticket);
}
}
I see that both classes contain almost equal methods and method implementations.
I think, it is not very good. What do you think? Or it is normal?
回答1:
Something like this should work for you, it's generally called the "Generic DAO Pattern".
public abstract class BaseDaoHibernate<T> extends HibernateDaoSupport implements Dao<T> {
private final Class<T> entityType;
protected BaseDaoHibernate(Class<T> entityType) {
this.entityType = entityType;
}
public T get(long id) {
return getHibernateTemplate().get(entityType, id);
}
public void save(T entity) {
getHibernateTemplate().save(entity);
}
public void remove(long id) {
getHibernateTemplate().delete(get(id));
}
}
and then:
public class TicketDaoHibernate extends BaseDaoHibernate<Ticket> {
public TicketDaoHibernate() {
super(Ticket.class);
}
}
and
public class UserDaoHibernate extends BaseDaoHibernate<User> {
public UserDaoHibernate() {
super(User.class);
}
}
回答2:
Use Generics and read this document. It's excellent.
回答3:
Add the following useful method to public abstract Dao<T>
:
public Class<E> getEntityClass() {
if (entityClass == null) {
Type type = getClass().getGenericSuperclass();
if (type instanceof ParameterizedType) {
ParameterizedType paramType = (ParameterizedType) type;
entityClass = (Class<E>) paramType.getActualTypeArguments()[0];
} else
throw new IllegalArgumentException("Could not guess entity class");
}
return entityClass;
}
Then your get
and remove
methods can be moved to Dao<T>
and rewritten as:
public T get(long id) {
return getHibernateTemplate().get(getEntityClass(), id);
}
public void remove(long id) {
getHibernateTemplate().delete(get(id));
}
来源:https://stackoverflow.com/questions/9006288/two-classes-with-almost-duplicate-code-inside