不幸的是,我感到主流開發人員仍然對此感到恐懼。
但是,比喻海格的蜘蛛,我會說泛型是被嚴重誤解的生物……:-)
我希望以下示例可以證明它們的實用性。
問題 – DAO(數據訪問對象)類具有通用的方法,例如保存,更新,刪除,loadAll ..,這在每個DAO類中都是必需的。
用這些通用方法編寫基類并使每個DAO對象對其進行擴展是遠遠不夠的,因為每個DAO類都代表一個不同的域類,因此通用方法簽名中使用的類型是不同的(盡管實現是相似的),例:
class OrderDAO {
//save method receive an Order
public void save(Order order){....}
//getAll method return Orders List
public List<Order> getAll(){...}
}class UserDAO{
//save method receive an User
public void save(User user){....}
//getAll method return Users List
public List<User> getAll(){...}
}
泛型如何幫助我們創建具有通用實現的基類,同時又保持方法簽名的類型安全?
首先,我們需要使用通用方法定義一個接口 :
/*** Base interface for CRUD operations and common queries*/
public interface IDaoBase<T> {public List<T> loadAll();public void save(T domain);public void update(T domain);public void delete(T domain);public T get(Serializable id);/*** Get list by criteria* @param detachedCriteria the domain query criteria, include condition and the orders.* @return* */public List<T> getListByCriteria(DetachedCriteria detachedCriteria);public List<T> getListByCriteria(DetachedCriteria detachedCriteria, int offset, int size);
}
請注意,我們利用泛型,因此每個方法簽名都有一個類型T,在已實現的DAO類中,每個域將是一個具體類型。
第二步是創建一個實現通用功能的抽象類:
public abstract class DaoBase<T> extends HibernateDaoSupport implements IDaoBase<T> {private Class<T> entityClass;@Autowiredpublic void setSession(SessionFactory sessionFactory){this.setSessionFactory(sessionFactory);}public DaoBase() {entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];}public List<T> loadAll(){return getHibernateTemplate().loadAll(entityClass);}public void delete(T domain) {getHibernateTemplate().delete(domain);}public void save(T domain) {getHibernateTemplate().saveOrUpdate(domain);}public void update(T domain) {getHibernateTemplate().merge(domain);}public T get(Serializable id) {T o = (T) getHibernateTemplate().get(entityClass, id);return o;}public List<T> getListByCriteria(DetachedCriteria detachedCriteria,int offset, int size) {return getHibernateTemplate().findByCriteria(detachedCriteria, offset, size);}public List<T> getListByCriteria(DetachedCriteria detachedCriteria) {return getHibernateTemplate().findByCriteria(detachedCriteria);}
}
就是這樣!
花一兩分鐘的時間檢查基礎對象如何以類型安全的方式實現通用功能。
實施新的DAO時,我們要做的就是:
1.接口,以擴展具體類型的IDaoBase
public interface DaoUser extends IDaoBase<User> {//<=Notice the User typing//Add any additional custom methods..public User getbyUsername(String username);public User getbyEmail(String email);
}
2.實現以具體類型擴展DaoBase
//This class has all the common methods, which are type safe for the User class
@Repository("daoUser")
public class DaoUserImpl extends DaoBase<User> implements DaoUser { //<=Notice the User typingpublic User getbyUsername(String username) {
// concrete implmentation ...}
因此,現在您知道使用泛型有多么強大。 希望它現在不再那么令人恐懼,更容易理解了……
參考: DAO層–在Gal Levinsky博客博客中,我們的JCG合作伙伴 Gal Levinsky進行救援的通用名 。
翻譯自: https://www.javacodegeeks.com/2012/08/dao-layer-generics-to-rescue.html