千万不要被标题吓倒,其实很简单。不然只能一辈子写面条式的程序了。特别是ASP程序员大多写都是3 IN 1 (超白金版:P)的程序,勉强能写成分层式的也是高手中的高手,这种大虾估计早就转型当系统分析员了。
一般来说系统大多分为三层(据说分三层很好):用户层、逻辑层、数据层。也可能不叫这几个名字,但是不管怎么说功能大体应该一样。说到功能请看下面
用户层:就是主要与用户打交道,也就是用户界面。什么输入框啊、提示信息啊的都在上面。因为用户对于系统而言都是foolish用户(不是用户都是fool,而是业务逻辑、数据关系不是每个用户都能了解的,如果都能了解就可以不用写程序,直接让用户操作数据库就好了),你不得不在这个层面上做出诸多限制和提示以便用户能正确的数据输入。这个层面一般都是原始数据采集以及数据最终的输出目标。这个就像一个商品的包装一样是给别人看的。跟业务逻辑数据处理没多大关系,不参与逻辑运算数据处理,说白了只能看啊!有人说了不是还有输入框吗?那不是只看啊?其实能输入框只是逻辑层的外延。因为逻辑层没有用户界面,只能依靠别人了。就像钓鱼,钩子就是用户层是用来看的,鱼杆、鱼线和绕线器还有钓鱼的人是逻辑层。鱼篓就是数据层了(不是很形象将就着用拉)。
逻辑层:是背地里进行的,用户毫无所知。系统要做的判断啊、截断原始数据啊、对原始数据进行算术运算啊、输出错误信息到用户层啊等等的。也就是说,用户输入“ABC”逻辑层要做的是,判断“ABC”是否符合业务逻辑需要,是则继续否则就是非法数据。逻辑层还要决定是提取“ABC”的“A”还是提取“B”传给数据层以保证数据层的正确运行。当然逻辑层还干很多事就不一一罗嗦了。当逻辑层完成了所有数据的处理判断,她就数据传递给数据层。
数据层:这里是跟数据库打交道,对于传入的数据,数据层决定写入还是添加到数据表中,添加到A表还是B表中。完成了返回成果或者错误信息或者数据集合给逻辑层。他就算完事了,其他什么都管。
好了介绍完了(一头汗啊:~)现在说好处,最典型的例子就是当业务逻辑发生变动的时候,只需要修改逻辑层就可以了其他各层不必改动。比如原来业务逻辑要求把用户输入的A加上B得数存入数据库。后来业务逻辑变了要求A减去B得数存入数据库。这时候就只需要修改业务逻辑层了。还有当数据库表字段类型变了,如果没有分层的话要把所有代码翻出来看那里用到这个字段,都要改(改完出错不出错那就不可知了)。有分层就简单了,对逻辑层传入的数据直接转类型就好了,一切照旧。真是居家旅游、杀人放火必备啊~~~:)
说了这么多到底怎么做才算是分层了?下面写个小例子
其实用.NET的就直接分了层了,用户界面和逻辑数据两层。
创建一个新项目,创建一个名为TEST.ASPX的文件。创建一个名为DBTEST.CS的类。打开TEST.ASPX成如下样子
<%@ Page language="c#" Codebehind="test.aspx.cs" AutoEventWireup="false" Inherits="MovieAdmin.test" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>test</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<asp:TextBox id="TextBox1" style="Z-INDEX: 101; LEFT: 296px; POSITION: absolute; TOP: 104px"
runat="server"></asp:TextBox>
<asp:TextBox id="TextBox2" style="Z-INDEX: 102; LEFT: 296px; POSITION: absolute; TOP: 136px"
runat="server"></asp:TextBox>
<asp:Button id="Button1" style="Z-INDEX: 103; LEFT: 504px; POSITION: absolute; TOP: 120px" runat="server"
Text="Button"></asp:Button>
</form>
</body>
</HTML>
就是两个文本框一个提交按纽
打开TEST.CS(就是查看TEST.ASPX的代码)
写如下
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace MovieAdmin
{
/// <summary>
/// test 的摘要说明。
/// </summary>
public class test : System.Web.UI.Page
{
protected System.Web.UI.WebControls.TextBox TextBox1;
protected System.Web.UI.WebControls.TextBox TextBox2;
protected System.Web.UI.WebControls.Button Button1;
private void Page_Load(object sender, System.EventArgs e)
{
// 在此处放置用户代码以初始化页面
}
#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.Button1.Click += new System.EventHandler(this.Button1_Click);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void Button1_Click(object sender, System.EventArgs e)
{
string text1 = TextBox1.Text.Trim();
string text2 = TextBox2.Text.Trim();
string text3 = text1 + test2;
dbtext td = new dbtext();
td.insert(text3);
}
}
}
再写DBTEST.CS类为如下
using System;
using System.Data.SqlClient;
namespace MovieAdmin
{
/// <summary>
/// dbtext 的摘要说明。
/// </summary>
public class dbtext
{
public dbtext()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
public string insert(string tempstr)
{
SqlConnection Conn = DB.DBOpen() ;
strSQL = "insert into [table](aaa) values('"+tempstr+"')" ;
PubLib.DB.DBExecute(Conn, strSQL) ;
Conn.Close();
return "成功" ;
}
}
}
……