在暑假里看了“Refactoring to Patterns”這本書,覺得很不錯(cuò)。里邊講到了很多在優(yōu)化編碼時(shí)可以用到的設(shè)計(jì)模式以及它們的用法。
我在編程時(shí),一般都是用Spring作為中間層管理資源,而用Hibernate作為ORM。用過Spring的人都知道Spring對Hibernate的支持方法較多,我常用的是直接繼承HibernateDaoSupport類。我們先來看一個(gè)類圖:

在是我在應(yīng)用中常用到的類結(jié)構(gòu)。因?yàn)閷τ谝粋€(gè)域模型來說,最基本的就是CRUD操作,所以將其放在Dao接口中,但是對于每個(gè)不同的域模型又有其特有的方法,則將其放在域模型對應(yīng)的接口(SomeSpecificDao)中。
這樣,對于最基本的CRUD操作就可以只需在BaseHibernateDao中實(shí)現(xiàn),這一點(diǎn)利用了Template Method設(shè)計(jì)模式。對于create(), delete()和modify()三個(gè)方法都可以簡單實(shí)現(xiàn),即調(diào)用HibernateTemplate中相應(yīng)的方法。對于findAll和findById,則可以借住Java的反射來實(shí)現(xiàn)。這里如果要利用反射且達(dá)到通用的目的,就需要將所有的域模型放在一個(gè)包中,并且有相同的命名規(guī)則,比如說如果域模型叫做User,那么相應(yīng)的Dao應(yīng)該以User開頭,不過這也是常用的方法。下面給出一小段代碼

/**
* A convenience and generic method for retrieving all models from the database
* @throws DataAccessException
*/

public List findAll() throws DataAccessException {
// TODO Auto-generated method stub
List models = new ArrayList();

try {
models = getHibernateTemplate().loadAll(
Class.forName(getClass().getName().replaceAll(
"HibernateDao", "").replaceAll("dao.hibernate",
"model")));

} catch (ClassNotFoundException exception) {
// TODO Auto-generated catch block
exception.printStackTrace();
}
return models;
} 以上給出的是findAll的實(shí)現(xiàn),findById也是一樣。這樣一來,就無需再在子類中重復(fù)編寫CRUD算法的實(shí)現(xiàn)了。
再有就是在編寫子類Dao中特有的find方法,因?yàn)槔肏ibernateTemplate中的execute方法來實(shí)現(xiàn),所以可以在BaseHibernateDao這個(gè)父類中編寫一個(gè)protected的方法,以便子類Dao調(diào)用,這個(gè)方法中包含了調(diào)用HibernateTemplate中execute方法的代碼:

/**
* Covenience method for retrieving objects by HQL
*/
protected Query find(final String query)

throws DataAccessException {
Query aQuery = (Query) getHibernateTemplate().execute(

new HibernateCallback() {

public Object doInHibernate(Session session) {
return session.createQuery(query);
}
});
return aQuery;
} 這樣在子類Dao中就可以直接調(diào)用該find方法來實(shí)現(xiàn),而不必每次都編寫繁瑣的execute方法。
以上的方法我都做過測試,在實(shí)現(xiàn)和應(yīng)用中沒有問題。在效率上可能會比在子類中實(shí)現(xiàn)要差一點(diǎn),因?yàn)閒ind*方法中用到了Java的反射,對效率會一定的影響,這是缺點(diǎn)之一。如果有哪位有更好的辦法,請?jiān)谠u論中寫出,歡迎大家進(jìn)行評判,謝謝……
我在編程時(shí),一般都是用Spring作為中間層管理資源,而用Hibernate作為ORM。用過Spring的人都知道Spring對Hibernate的支持方法較多,我常用的是直接繼承HibernateDaoSupport類。我們先來看一個(gè)類圖:

在是我在應(yīng)用中常用到的類結(jié)構(gòu)。因?yàn)閷τ谝粋€(gè)域模型來說,最基本的就是CRUD操作,所以將其放在Dao接口中,但是對于每個(gè)不同的域模型又有其特有的方法,則將其放在域模型對應(yīng)的接口(SomeSpecificDao)中。
這樣,對于最基本的CRUD操作就可以只需在BaseHibernateDao中實(shí)現(xiàn),這一點(diǎn)利用了Template Method設(shè)計(jì)模式。對于create(), delete()和modify()三個(gè)方法都可以簡單實(shí)現(xiàn),即調(diào)用HibernateTemplate中相應(yīng)的方法。對于findAll和findById,則可以借住Java的反射來實(shí)現(xiàn)。這里如果要利用反射且達(dá)到通用的目的,就需要將所有的域模型放在一個(gè)包中,并且有相同的命名規(guī)則,比如說如果域模型叫做User,那么相應(yīng)的Dao應(yīng)該以User開頭,不過這也是常用的方法。下面給出一小段代碼



* @throws DataAccessException


















再有就是在編寫子類Dao中特有的find方法,因?yàn)槔肏ibernateTemplate中的execute方法來實(shí)現(xiàn),所以可以在BaseHibernateDao這個(gè)父類中編寫一個(gè)protected的方法,以便子類Dao調(diào)用,這個(gè)方法中包含了調(diào)用HibernateTemplate中execute方法的代碼:

















以上的方法我都做過測試,在實(shí)現(xiàn)和應(yīng)用中沒有問題。在效率上可能會比在子類中實(shí)現(xiàn)要差一點(diǎn),因?yàn)閒ind*方法中用到了Java的反射,對效率會一定的影響,這是缺點(diǎn)之一。如果有哪位有更好的辦法,請?jiān)谠u論中寫出,歡迎大家進(jìn)行評判,謝謝……