Posted on 2007-02-27 17:49
冰浪 閱讀(1739)
評論(4) 編輯 收藏 所屬分類:
WEB開發
?????
在上一篇日記中我已經提到了松耦合,在一個類中,我們也盡量不要與別的對象發生緊密的聯系,讓一個類符合封裝性,類與類之間做到松耦合,避免牽一發而動全身。繼承最大的缺點就是打破封裝,所以組合優于繼承。在分層軟件結構中,我們也應該盡量做到各層之間松耦合,使某一層的改動對其它層的影響減到最小,這樣利于軟件功能修改和擴充,利于軟件的移植。
上篇里,我提到定義
Dao
接口的目的最終是為了做到分層結構間松耦合,但僅利用上篇的方法并不能達到目的,比如在
CSUOA
里,在具體實現
Dao
實例如
OauserDao.class
是采用
Hibernate
進行,假如后來我覺得
Hibernate
的效率不夠高,想換成別的
ORM
框架如
JDO
進行改進呢?此時我要做的就是再寫一個有相應實例方法的
JdoOauserDao.class
類,它實現了
Dao
接口類,因此它也具有
Dao
接口類型。在業務層調用時,我需要將所有
Dao dao = new OauserDao();
這樣的代碼替換成
Dao dao = new JdoOauserDao;
如果有大量的這樣的代碼存在,我也只能相應地一一替換。從這可以看出,這樣做使業務層與持久層之間的耦合非常高,維護的成本也相當高,而這是我所不希望的。
一個設計精良的系統,在設計之前就必須考慮到將來的種種變動,并要提供可簡單實現的方案,這樣才不至將大量的人力物力浪費在將來的軟件維護上。
為了實現這個目標,在
CSUOA
中就要用到設計模式中的工廠模式,它屬于創建模式。先來看我是如何實現這個工廠類的:
//DaoFactory.class
工廠類
public class DaoFactory{
?
? static final String OAUSER_DAO="OauserDao.class";
? static final String MAIL_DAO="MailDao.class";
? static final String MESSAGE_DAO="MessageDao.class";
?
? public static Dao getInstance(String daoNameStr){
??????? try{
???????????????????? Class c = Class.forName(daoNameStr);
???????????????????? dao=(Dao)c.newInstance();
????????????? }catch(Exception e){
???????????????????? e.printStackTrace();????????????
????????????? }
????????????? return dao;
? }
}
?
由上述代碼中可以看出,在這個工廠類里有一個靜態方法
getInstance()
,用于獲取具體的
Dao
實例類,而我們也看到其返回類型為
Dao
接口類型,而不是
OauserDao
等
Dao
的實例類類型,這就為所有的
Dao
實例類對象提供了統一的獲取途徑。從這可以看出接口類的作用。如何使用這個工廠類呢?是這樣的:
Dao dao = DaoFactory.getInstrance(“OAUSER_DAO”)
,而不是直接
new
一個對象出來了。而當要做出之前提出的改動時,我就只要將這個
DaoFactory
類里的
static final String OAUSER_DAO="OauserDao.class";
改為
static final String OAUSER_DAO="JdoOauserDao.class";
就可以了,業務層代碼基本上不需要改動,這就實現了業務層與持久層間的松耦合。
在業務層里,我們始終只通過
Dao
接口進行操作,并沒有出現如
OauserDao
這樣代碼,好像不存在一樣,而且我們根本也不需要知道有這樣的類存在。從這里我們可以進一步體會接口的用法及其方便性。
?
設計模式,在我接觸它之前,編寫程序從來不會考慮那么多,總認為要得到一個對象時,
new
一個出來是天經地義的事,也根本不會考慮什么松耦合之類的問題。學習設計模式,能讓自己在面向對象編程思想上得到升華。