Posted on 2007-02-27 17:49
冰浪 阅读(1731)
评论(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
一个出来是天经地义的事,也根本不会考虑什么松耦合之类的问题。学习设计模式,能让自己在面向对象编程思想上得到升华。