日期:2010-03-01  浏览次数:20466 次

问题由来

最近在研究适合团队开发的web架构解决方案,该架构即要适合分工协作又要有一定扩展性,适合不同的数据库需要,因此我查阅了一些资料,初步构想出了一套架构,请各位多多指教。

探索

web开发架构最经典莫过于三层架构,表示层、逻辑层、数据处理层。

数据访问层:其功能主要是负责数据库的访问。

业务逻辑层:是整个系统的核心,它与这个系统的业务(领域)有关。

表示层:是系统的UI部分,负责使用者与整个系统的交互。理想的状态是表示层不应包括系统的业务逻辑。

这些是经典的解释,如果要适合不同的数据库则需要加入工厂模式,里面用面向接口的方式进行多态调用。是不是这有点像petshop了。所以架构的初步设想是这样:

clip_image001

下面以获取用户信息为例,简述这个架构的流程:(以下为类似petshop的经典做法,了解的可以略过)

step 1 、首先我们应该建立项目所需的实体模型,在这里新建用户信息的实体模式,UserInfo.cs。该类保存在Model项目里。

step 2 、我们再将项目的单元功能写到相关的接口中,这里以获取用户信息功能为例。在IDAL项目里新建IUser接口。

        //根据用户ID获取用户信息
        UserInfo GetUserById(int userId);

step 3、完成了接口,我们就要实现它,现在我们用sqlserveroracle两种数据库访问方式来实现它。以下是SqlserverDAL中User类对接口的现实:

public class User:IUser
    {

       
        public UserInfo GetUserById(int userId)
        {
         //实现操作           

        }

    }

OracleDAL中现实方式类似。。。。

step 4、在此数据库访问层应该就基本写好了,下面应该给逻辑层调用了,但是两种实现方式怎么调用呢,或者说怎么有选择的调用它呢,petshop是这样处理的,在DALFactory中的DataAccess类,利用反射载入程序集从而实例化所需要的类:


        private static readonly string path = ConfigurationManager.AppSettings["WebDAL"];
        public static IUser CreateUser()
        {  

            string className = path + ".User";
            return (IUser)Assembly.Load(path).CreateInstance(className);

        }

至于要选择哪个数据库访问层,在配置文件里配置一下WebDAL。如:<add key="WebDAL" value="SQLServerDAL"/>。

这样就基本解决了逻辑层和数据访问层的耦合。

step 5、下面就该写逻辑层了,在BLL里面创建User.cs类。大致如下:

public class User
   {
       private static readonly IUser dal = DALFactory.DataAccess.CreateUser();

       public UserInfo GetUserInfo(int userId) {
            return dal.GetUserById(userId);
        }

   }

是不是觉得BLL毫无意义,因为它只是对数据访问层方法的简单调用,但并不是这样的,这里只有一个简单的事例,在实际项目中一个BLL里面处理的可能是一个非常复杂的逻辑,而这个复杂逻辑的结果才提供给表示层显示。

step 6、最后是表示层,好像没什么可说的,把从BLL取出来的数据绑定到你的页面就行了。

以上是仿petshop的架构设计,看起来没什么质疑的地方,毕竟是微软的经典案例。你可能抱怨的地方有两点,一是层是不是有点多,关系过于复杂;二如果我需要改变或增加一个数据库字段,那不是会很痛苦,因为要节联修改。这两个问题,我都没办法解决,一如果说过于层过于多而繁琐,那么下面我写的好像更为复杂,原谅。。。。二、鄙人觉得凡是分层开发,只要以数据库字段为依据的建立实体模型,都会存在节联修改的问题。除非全部用DataTable,那么在BLL、表示层调用