抽象工厂模式的缺点是在每一个使用到数据访问的地方都需要实例化一个具体的工厂类,然后调用各个方法返回具体的实
现了数据访问接口的数据访问类对象,再调用该对象实现具体的数据访问操作
简单工厂改进:
去除抽象工厂和具体的工厂类,用一个简单工厂代替,简单工厂里面只有一个DataAccess类,这个类里面的每一
个类都返回一个数据访问层对象,而该对象具体访问的数据库类型由一个只读的成员存储,在每一个函数中通过switch-case
语句来判断应该返回什么类型的数据库访问对象
进一步演变:
上面的方式有一个很大的缺点——每一个函数中都需要一个分支语句判断,如果再换一个数据库,就需要在每
一个函数中的分支语句中添加相应的case子句,这就不利于程序的扩展了,这里就可以通过反射的技术实现以不变应万变
,在每一个创建数据访问对象的函数中不再用switch-case分支语句了,而是根据程序集和类名来动态创建对象,然后赋给一
个接口引用,客户端就可以通过这个接口引用访问数据了
加入配置文件:
程序集的名称可以选择存储在DataAccess类中的一个只读字段中,用常量写死在程序中,或放在配置文件中
保持各个数据库访问类中的类名一致:
需要注意的一点:不同的数据库访问类的类名应该保持“一致”,如这样的情况,DataAccess类中有这样一个方法CreateUser,
这个方法需要通过程序集的名字和类名来创建实现了IUser接口的对象,如果在AccessDAL中的类名是User1,而SQLServerDAL中的类名是
User2,显然在DataAccess的函数中就不能以统一的方式创建对象了Assembly.Load(AssemblyPath).CreateInstance(classNamespace),而如果
两个类的名字都是User或一个是AccessUser,另一个是SQLServerUser,在创建对象的时候在配置文件中就可以只获得程序集路径和命名空间(外加一个数据库名),当然我们也可以在配置文件中为每一个dal类提供一个名称信息也是可以的,但那样就显得很没有必要了。
DataAccess类中提供CreateObject方法:
private static object CreateObject( string classNamespace)
DataAccess类一般是一个static的类,还会在类内部提供一个公用的创建对象的方法(如上),在类的其它方法中使用该方法创建指定的类对象,然后将其转化为相应的接口返回给bll层,如:return (IUser)CreateObject(ClassNamespace);
启用缓存:
放射的效率不高,如果每一次创建对象的时候都需要通过反射重新创建,效率很很低,所以可以使用缓存的方式优化一下,就是在DataAccess类的CreateObject方法中做如下处理:先在缓存中查找有没有当前要创建的对象,如果有则直接返回,如果没有则创建,并将其置于缓存中再返回。
DataCache类提供了缓存的功能
|