.net三层架构分析

资料:http://bbs.51aspx.com/showtopic.aspx?topicid=6261&forumpage=1&typeid=-1&page=6

 

        实现步骤过程
        1、创建Model,实现业务实体。
        2、创建IDAL,实现接口。
        3、创建DAL,实现IDAL接口里的方法。
        5、创建BLL,调用DAL,得到程序集指定类的实例,完成数据操作方法。
        6、创建WEB,调用BLL里的数据操作方法。

以一个实际项目对三层架构分析
一. 三层架构的概念
        三层架构是基于模块化程序设计的思想,为实现分解应用程序的需求,而逐渐形成的一种标准模式的模块划分方法。此模型将应用程序划分为三个层次:
①表现层:负责处理用户的输入和向用户输出,但并不负责解释其含义。有时候出于对效率的考虑,这一层可能会在向上传输用户输入之前进行合法性验证。这一层通常采用前端工具(如 VB、VC 和 Java)开发。②业务逻辑层:这一层是上下两层的纽带,它建立实际的数据库连接,根据用户的请求生成检索语句或更新数据库,并把结果返回给前端界面显示。这一层通常以动态链接库的形式存在,并注册到服务器的注册表中,它与前端界面通讯的接口符合某一特定的组件标准(如 COM 组件)。可以用任何支持这种标准的工具开发。③数据访问层:负责实际的数据存储和检索。
在业务逻辑组织可分为三种主要的模式:
事务脚本:事务脚本就是这样一个过程,聪表示层获得输入、进行校验和计算处理、将数据存储到数据库中以及调用其他系统的操作等。然后,该过程将更多的数据返回给表示层,中间可能要进行大量的计算来组织和整理返回值。基本的组织方式是让每个过程对应用户可能做得一个动作。所以我们可以将这一模式想象成一个动作或业务事物的脚本。
领域模型:这是一种面向对象的思想,不再是有一个过程来控制用户某一动作的逻辑,而是 有每一个对象都承担一部分相关的逻辑。
表模块:这一模式咋看起来与领域模型相似,区别在于领域模型对数据库中每一个表对应一个类,二表模块只有一个公共类,表模块设计成与记录集一起工作,因此,在一个用来处理公共类的表模块中客户需要首先对数据库进行查询生成一个记录集,然后以记录集为参数创建其中一个对象。
二. 实例分析:
在这一次项目实践中我们还增加了几层:
数据访问层接口(IDAL)
业务实体层(Model)
数据访问组件基础类(DBUtility)
这是对三层架构的一种扩展。
下面咋表格表示各层次以及各层次间的关系:
ID        项目        描述        用途        项目引用关系
1        WEB        变现层        Web页和控件        引用BLL
2        BLL        业务逻辑层        业务逻辑组件        引用IDAL,MODEL,使用DALFactory
3        IDAL        数据访问层接口定义        每个DAL实现都要实现的一组接口
        引用 Model
4        Model        业务实体        传递各种数据的容器        我引用
5        DAL
        数据访问层
        Microsoft SQL Server特定的Pet Shop DAL实现,使用了IDAL接口
                引用 Model和IDAL,被DALFactory加载的程序集,实现接口里的方法。
6        DBUtility
        数据库访问组件基础类
                无引用
        实现步骤过程
        1、创建Model,实现业务实体。
        2、创建IDAL,实现接口。
        3、创建DAL,实现IDAL接口里的方法。
        5、创建BLL,调用DAL,得到程序集指定类的实例,完成数据操作方法。
        6、创建WEB,调用BLL里的数据操作方法。
        
程序表示各层次及其之间的关系:
        Model层:
        public class ChannelInfo
    {
        private int channelId;
        private string channelName;
        private string resourceType;
        public ChannelInfo() { }
        public ChannelInfo(int channelId, string channelName, string resourceType)
        {
            this.channelId = channelId;
            this.channelName = channelName;
            this.resourceType = resourceType;
        }
        public int ChannelID
        {
            get { return channelId; }
        }
        public string ChannelName
        {
            get { return channelName; }
        }
        public string ResourceType
        {
            get { return resourceType; }
        }
}
IDAL层:
using DBXJ.Model;
namespace DBXJ.IDAL
{
    public interface IChannel
    {
        bool InsertChannel(ChannelInfo channel);
        bool DeleteChannelByID(int channelID);
        bool UpdateChannel(ChannelInfo channel);
        IList<ChannelInfo> GetChannelsByResourceType(string resourceType);
        int GetChannelID(string resourceType, string channelName);
        string GetChannelNameByID(int channelID);
        IList<ChannelInfo> GetAllChannels();
    }
}
DBUtility 层:
namespace DBXJ.DBUtility
{
    /// <summary>
    /// The SqlHelper class is intended to encapsulate high performance,
    /// scalable best practices for common uses of SqlClient.
    /// </summary>
    public static class SqlHelper
    {
        //Database connection strings
        public static readonly string SqlConnectionStr = ConfigurationManager.ConnectionStrings["SqlServerConnctionStr"].ConnectionString;
        
        // Hashtable to store cached parameters
        private static Hashtable parmCache = Hashtable.Synchronized(new Hashtable());
        public static int ExecuteNonQuery(string connectionString, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {}
        public static int ExecuteNonQuery(SqlConnection connection, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {}
        public static int ExecuteNonQuery(SqlTransaction trans, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {}
        public static SqlDataReader ExecuteReader(string connectionString, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {}
        public static object ExecuteScalar(string connectionString, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {}
        public static object ExecuteScalar(SqlConnection connection, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {}
        public static void CacheParameters(string cacheKey, params SqlParameter[] commandParameters) {}
        public static SqlParameter[] GetCachedParameters(string cacheKey) {}
        private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms) {}
    }
}
DAL 层:
using DBXJ.Model;
using DBXJ.IDAL;
using DBXJ.DBUtility;
namespace DBXJ.SQLServerDAL
{
    public class ChannelQuery : IChannel
    {
        public bool InsertChannel(ChannelInfo channel)
        {
            SqlParameter[] cmdParams = new SqlParameter[]{
                new SqlParameter("@ChannelID",channel.ChannelID),
                new SqlParameter("@ChannelName",channel.ChannelName),
                new SqlParameter("@ResourceType",channel.ResourceType)
            };
            int val = SqlHelper.ExecuteNonQuery(SqlHelper.SqlConnectionStr, CommandType.StoredProcedure, StoredProcedure.InsertChannel.ToString(), cmdParams);
            return val == 1;
        }
        public bool DeleteChannelByID(int channelID) {}
        public bool UpdateChannel(ChannelInfo channel) {}
        public IList<ChannelInfo> GetChannelsByResourceType(string resourceType) {}
        public int GetChannelID(string resourceType, string channelName) {}
        public string GetChannelNameByID(int channelID) {}
        public IList<ChannelInfo> GetAllChannels(){}
       }
        }
        
BLL 层:
using DBXJ.Model;
using DBXJ.IDAL;
using DBXJ.SQLServerDAL;
namespace DBXJ.BLL
{
    public class ChannelBLL
    {
        private static readonly IChannel channelDAL = new ChannelQuery();
        /// <summary>
        /// 增加一个频道信息
        /// </summary>
        /// <param name="channel"></param>
        /// <returns></returns>
        public bool AddChannel(ChannelInfo channel)
        {
            if (channel == null)
            {
                return false;
            }
            return channelDAL.InsertChannel(channel);
        }
        public bool DeleteChannel(int channelID) {}
        public bool UpdateChannel(ChannelInfo channel) {}
        public IList<ChannelInfo> GetChannelsByResourceType(string type) {}
        public int GetChannelID(string resourceType, string channelName) {}
        public string GetChannelName(int channelID) {}
        public IList<ChannelInfo> GetAllChannels(){}
        }
}
WEB 层:
using DBXJ.BLL;
using DBXJ.Model;
using System.Text;
using System.IO;
public partial class Default4 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
    }
    protected void Button1_Click(object sender, EventArgs e)
    {int id = int.Parse(this.DropDownList1.SelectedItem.Text);
        string name = this.TextBox1.Text;
        string type = this.DropDownList3.SelectedItem.Text;
        ChannelInfo channel = new ChannelInfo(id,name,type);
        bool text = new ChannelBLL().AddChannel(channel);
        if (text)
        {
            Response.Write("<script language='javascript'>alert('恭喜你,上传成功!');</script>");
        }
        else
        {
            Response.Write("<script language='javascript'>alert('上传失败!');</script>");
        }
        }
}
三. 三层架构的优缺点:
优点:
  1、开发人员可以只关注整个结构中的其中某一层;
  2、可以很容易的用新的实现来替换原有层次的实现;
  3、可以降低层与层之间的依赖;
  4、有利于标准化;
  5、利于各层逻辑的复用。
    6、扩展性强。
    7、安全性高。用户端只能通过逻辑层来访问数据层,减少了入口点,把很多危险的系统功能都屏蔽了。
     8、项目结构更清楚,分工更明确,有利于后期的维护和升级
缺点:
  1、降低了系统的性能。这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。
  2、有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码
    3、增加了代码量,增加了工作量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值