Adapter模式实现数据访问层在B/S与C/S系统间的随意切换


问题描述:
  如果我们做了一个B/S系统,系统需要对数据库进行操作。假定将来要将该B/S转变为C/S系统的话,考虑到数据库安全等原因,客户端无法对数据库直接操作,所以必须采用分布式架构实现界面、业务与数据访问层的分离。比如,我们可以采用WebService的方式。
  这样一来,数据访问层以上的代码就必须修改,因为原本调用数据访问类的代码,现在必须改成对WebService的调用。为解决这个问题,我在项目中采用了以下
方案。
  先上架构图

 
  架构图中的“ClinicService“为业务类,它需要对数据访问类进行调用。
  IClinicDao为数据访问类的接口,ClinicService调用该接口。然后我们可以通过反射的机制对ClinicService中的IClinicDao进行依赖注入(Factory Pattern)。
  ClinicDao为该接口的实现,它最终实现对数据库的操作。如果是B/S程序,ClinicService调用的就是ClinicDao。
  而对于C/S系统,ClinicDao只能部署在服务器端,我们可以通过ClinicWebService.asmx将ClinicDao的接口包装成WebService接口。
  好了,我们再看客户端程序。客户端程序采用.net WebService代理类的方式,自动生成ClinicWebServiceSoapClient。然后让上层程序调用该代理类。
  这样问题就出现了,ClinicService依赖的是接口IClinicDao,而代理类并没有实现该接口。我们无法将ClinicWebServiceSoapClient绑定到ClinicService中。而我的解决方案是:采用Adapter模式,创建一个类ClinicDaoWrap,该类继承 ClinicWebServiceSoapClient,然后再实现接口IClinicDao。这样一来,ClinicDaoWrap即具有ClinicWebServiceSoapClient的方法,也能绑定到ClinicService中了。
  ClinicDaoWrap的代码很简单:
    public class ClinicDaoWrap : ClinicWebServiceSoapClient,IClinicDao
    {
        
public ClinicDaoWrap()
        {
        }
    }



  有了这个架构,我们只要简单地修改配置就能实现B/S到C/S的随意切换了。下面是配置文件:
1.B/S下的配置
  <object id="ClinicService" type="Clinic.Service.ClinicService,Clinic.Service">
    
<property name="_clinicDao">
      
<object type="Clinic.DAL.ClinicDao,Clinic.DAL">
      
</object>
      
<!-- object type="Clinic.ServiceReference.ReferencesWarp.ClinicDaoWrap,Clinic.ServiceReference">
      
</object -->
    
</property>
  
</object>



2.C/S下的配置
  <object id="ClinicService" type="Clinic.Service.ClinicService,Clinic.Service">
    
<property name="_clinicDao">
      
<!-- object type="Clinic.DAL.ClinicDao,Clinic.DAL">
      
</object -->
      
<object type="Clinic.ServiceReference.ReferencesWarp.ClinicDaoWrap,Clinic.ServiceReference">
      
</object>
    
</property>
  
</object>



不知道园子的朋友有没有遇到相同的问题,希望我的方法能帮助大家解决一些实际问题,欢迎大家指正与批评。
posted on 2009-08-11 12:50  snowwolflibo  阅读(556)  评论(3编辑  收藏  举报