我对N层架构的理解

            以前没太多关注各多层架构的设计,一直以来都是用的三层架构做网站,最近对N层架构有些兴趣,就稍微研究了一下,由于自己也没怎么用过,也是才学习,中间可能有些错误,请大家指正。
            ASP.NET的框架不管有多少层架构,都脱离不了最基本的三层:表现层,业务层,数据访问层。
      
      整个过程的来回都跟请求和数据有关,往右发送请求,往左响应请求返回数据。
      最简单的三层结构:Default.aspx——>BLL——>SQLHelper
                                Default.aspx<——BLL<——SQLHelper
     多层架构既然是基于三层架构的,它是对最基础的三层结构进行再抽离,那么就可以在三层架构的基础上再至少抽出一个中间层,是最原始的三层架构之间的桥梁,它起到一个衔接作用。试想一个业务比较复杂的网站,BLL的代码量会比较庞大,基本的三层显然是不够用的。我的做法是在三层的基础之上,先给Web和BLL之间搭一座桥,我叫它BLLManager,它的作用就是来统一管理所有的BLL类;这还不够,我把和SQLHelper相关的数据访问类都放到DAL中(以前的做法是用BLL来访问SQLHelper),这就相当于业务的数据都在DAL中请求和获得;然后我再在BLL和DAL中抽出一个类DALFactory用来管理所有的DAL(除了SQLHelper)。现在基本的结构如下图(不知道我的理解对不对,希望大家指正):


      使用N层架构的效果:每一层都可以在仅仅更改很少量的代码后,就能放到物理上不同的服务器上使用,因此结构灵活而且性能更佳。此外,每层做些什么其它层是完全看不到的,因此更改、更新某层,都不再需要重新编译或者更改全部的层了。这是个很强大的功能。例如,如果把数据访问代码与业务逻辑层分离,当数据库服务器更改后,你只需要更改数据访问的代码,因为业务逻辑层是不变的,因此不需要更改或者重新编译业务逻辑层。

下面我给了个简单的例子:
Default.aspx
ContractedBlock.gif ExpandedBlockStart.gif Code
ExpandedBlockStart.gifContractedBlock.gif<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    
<title></title>
</head>
<body>
    
<form id="form1" runat="server">
    
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
    
<asp:Button ID="Button1" runat="server" Text="查询" onclick="Button1_Click" />
    
<div id="infoList" runat="server">
        
    
</div>
    
</form>
</body>
</html>
Default.aspx.cs
ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
using Model;
using Test.Common;
namespace Test
ExpandedBlockStart.gifContractedBlock.gif
{
    
public partial class _Default : System.Web.UI.Page
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
protected void Page_Load(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
        }


        
protected void Button1_Click(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
string name = this.TextBox1.Text;
            StringBuilder info = new StringBuilder();
            info.Append("<table border='1'>");
            info.Append("<tr>");
            info.Append("<td>编号</td>");
            info.Append("<td>姓名</td>");
            info.Append("<td>入职时间</td>");
            info.Append("</tr>");
             IList<Emp> empList = BLLManager.Instance.EmpBLL.GetEmpList(name);
            
if (empList!=null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
foreach (Emp emp in empList)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    info.Append("<tr>");
                    info.Append("<td>"+emp.EmpId+"</td>");
                    info.Append("<td>"+emp.EmpName+"</td>");
                    info.Append("<td>" + String.Format("{0:yyyy-MM-dd}", emp.HireDate) + "</td>");
                    info.Append("</tr>");
                }

            }

            info.Append("</table>");
            
this.infoList.InnerHtml = info.ToString();
        }

    }

}

Emp.cs
ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Text;

namespace Model
{
    
public class Emp
    {
        
private int empId;
        
private string empName;
        
private DateTime hireDate;
        
public int EmpId
        {
            
get { return empId; }
            
set { empId = value; }
        }
        
public string EmpName
        {
            
get { return empName; }
            
set { empName = value; }
        }
        
public DateTime HireDate
        {
            
get { return hireDate; }
            
set { hireDate = value; }
        }
    }
}
BLLManager.cs
ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Web;
using BLL;
namespace Test.Common
ExpandedBlockStart.gifContractedBlock.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
    
/// BLLManager类,统一管理所有的BLL,作为Web层和BLL层的中间层,用来返回BLL类库中某个类的实例
    
/// 这个类采用单例模式,确保系统中只有一个BLLManager类
    
/// </summary>

    public class BLLManager
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
private static BLLManager _instance;
        
private BLLManager()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
        }

        
public static BLLManager Instance
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (_instance == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
lock (typeof(BLLManager))
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        
if (_instance == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
{
                            _instance = new BLLManager();
                        }

                    }

                }

                
return _instance;
            }

        }

        
public EmpBLL EmpBLL
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return new EmpBLL(); }
        }

        
    }

}


EmpBLL.cs


ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Text;
using DAL;
using Model;

namespace BLL
ExpandedBlockStart.gifContractedBlock.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
    
/// 
    
/// </summary>

    public class EmpBLL
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
public EmpBLL()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            DAL = DALFactory.CreateEmpDAL();
        }

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// DAL作为EmpBLL的属性,用来get,set对应的EmpDAL类的实例
        
/// </summary>

ExpandedSubBlockStart.gifContractedSubBlock.gif        public EmpDAL DAL getset; }
        
public IList<Emp> GetEmpList(string name)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
return DAL.GetEmpListByName(name);
        }

    }

}


DALFactory.cs
ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Text;
using Model;
using DAL;
namespace BLL
ExpandedBlockStart.gifContractedBlock.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
    
/// DALFactory用来管理所有的DAL类,实例化DAL,所有的DAL类都在这里被实例化
    
/// </summary>

    public class DALFactory
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
public static EmpDAL CreateEmpDAL()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
return new EmpDAL();
        }

    }

}


EmpDAL.cs
ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using Model;
namespace DAL
ExpandedBlockStart.gifContractedBlock.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
    
/// 这一层是数据访问层,和实体类打交道,最终返回的也是一些对象
    
/// 我的理解是SQLHelper是数据库访问层,是和数据库直接相关的,这应该是两个不同的层次
    
/// </summary>

    public class EmpDAL
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
        
public IList<Emp> GetEmpListByName(string name)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            List<Emp> items = null;
ExpandedSubBlockStart.gifContractedSubBlock.gif
            SqlParameter[] parms = new SqlParameter[]{
                                    
new SqlParameter("@Name",SqlDbType.VarChar,20)
            }
;
            parms[0].Value = name;
            
//调用存储过程
            using (SqlDataReader reader = SQLHelper.ExecuteReader(SQLHelper.CONN_STRING, CommandType.StoredProcedure, "EmpsGetByName", parms))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
while(reader.Read())
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
//isDBNull()
                    
// 在c#中,进行数据库查询时使用IsDbNull 方法判断数据库中字段值是否存在(注意不是判断是否空值或0)                     //。将字段所在的行key作为参数传给IsDbNull 方法,此方法对其值进行判断,如果字段值不存在或缺少值则返                    //回Ture,如果字段值存在则返回False。
                    
//此方法能方便地对数据库中值的存在与否和是否缺失进行判断,避免了空值的干扰。

                    
int empid = !reader.IsDBNull(0)?reader.GetInt32(0):0;
                    
string empname = !reader.IsDBNull(1)?reader.GetString(1):string.Empty;
                    DateTime hiredate = !reader.IsDBNull(2)?reader.GetDateTime(2):DateTime.Today;
                    Emp emp = new Emp();
                    emp.EmpId = empid;
                    emp.EmpName = empname;
                    emp.HireDate = hiredate;
                    
if(items==null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        items = new List<Emp>();
                    }

                    items.Add(emp);
                }

            }

            
return items;
        }

    }

}

            SQLHelper.cs我就不贴了。下面有整个源码(包含sql)的下载
             /Files/psunny/N-tier-structure.rar
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值