`
long_yu2
  • 浏览: 312240 次
社区版块
存档分类
最新评论

打开思维,让分层飞一会

 
阅读更多
  • 认识分层:

做开发也有几年了,在开发软件的过程中,分层式结构是最常见的,也是非常重要的。

其实,分层只是一种思想,与层数无关,不管是分为三层,还是五层,抑或是七层,这些分法都是为了让我们的项目适应变化,可重用,方便程序员的开发。

那些所谓的代名词:

表示层这一层是给用户的界面;就是和用户交互的,用于显示和接收用户输入的数据的。

2011-03-24_112646

数据层:这一层就是负责数据库的访问,其实就是对数据表的增删改查等操作。

2011-03-24_112818

业务逻辑层:这一层处于表示层和数据层中间,可以看出这一层的重要性。我给他起了另外一个名字叫“华丽的承上启下”。这一层主要完成业务的规则定制、业务流程实现等任务。

2011-03-24_113539

各司其职,分层治之:

我们将整个项目分层,这样可以做到各司其职,各管各家,分开治之。

我们的开发人员可以只关注更个结构中的其中一层,其余的都可以不用去照顾,这样每个成员都有自己的关注点,使分工很明确。

维护也就显得非常容易,只要用新的实现替换原有层次的实现即可;

分层治之,可以让层层之间依赖性降低,达到解耦的目的。

我们也很容易的发现,数据层的代码复用率高,而且分层之后各层之间的逻辑也得到了复用。

我们在开发的时候也可以用多语言进行开发。

层,要合理的去分:

分层就像设计模式一样,要想用好不是容易的事情,我也是正在摸索中,在项目中积累经验。

但是我知道,层不是说分三层就分三层,分五层就五层,七层就七层的,要看具体的项目工程。一如设计模式,不是说看懂了这个设计模式,我做项目中一定要用到它;用不好有时候会吃亏的。

项目实战--分一回:

rose架构图:

与之对应的vs解决方案:

2011-03-24_111111表示层:

2011-03-24_112646

表示层代码:

''' 
    ''' 单击确定按钮
    ''' 
    ''' 
    ''' 
    ''' 2011-3-20 13:21 by lfsf802
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If Trim(txtUsername.Text) = "" Or Trim(txtPwd.Text) = "" Or Trim(cmbStatus.Text) = "" Then
            MsgBox("信息不能为空")
            wrongReturn()
            Exit Sub
        End If
        If blluserInfo.checkRecord(Trim(txtUsername.Text), Trim(txtPwd.Text), Trim(cmbStatus.Text)) Then
            frmMain.show()
        Else
            MsgBox("输入信息错误,请您重新输入")
            wrongReturn()
            Return
        End If
    End Sub

业务逻辑层代码:

''' 
    ''' 判断登录
    ''' 
    ''' 用户名
    ''' 密码
    ''' 身份
    ''' 是否登录成功
    ''' 2011-3-20 15:14 by lfsf802
    Public Function checkRecord(ByVal userName As String, ByVal password As String, ByVal status As String) As Boolean
        entityUserInfo.UserName = userName
        Dim entityuser As New Entity.UserInfo
        iuserinfo = dataaccess.CreateUserInfo
        entityuser = iuserinfo.ReturnRecord(entityUserInfo)
        If entityuser.Password = password And entityuser.StatusType = status Then
            Return True
        Else
            Return False
        End If
    End Function
''' 
    ''' 返回一条用户信息记录
    ''' 
    ''' 一条用户信息
    ''' 一条用户信息记录
    ''' 2011-3-19 16:08 by lfsf802
    Public Function ReturnRecord(ByVal entityUserInfo As Entity.UserInfo) As Entity.UserInfo
        iuserinfo = dataaccess.CreateUserInfo
        Return iuserinfo.ReturnRecord(entityUserInfo)
    End Function

数据层:

这里用了抽象工厂设计模式,并且用到了反射技术和配置文件来辅助抽象工厂。

'===============================================================
    '这个是用反射+抽象工厂的数据库访问方式,我们考虑的是可以不在程序
    '写具体让实例化那个类,而是根据db的值来去某个地方找应该实例化哪个
    '类,这样就和select说再见了。
    '用到反射技术,将greateInstance里面的变量值初始化成想要的类,而实
    '例化的依据就是db变量来决定的。这样就除去了switch判断的麻烦。
    '================================================================
    Private ReadOnly AssemblyName As String = "DAL"
    '这是反射+配置文件实现数据库访问方式,这样我们只要在配置文件中写明
    '是哪个数据库就ok了,连dataAccess类也不用更改了
    Private ReadOnly db As String = System.Configuration.ConfigurationSettings.AppSettings("DB")
    'Private ReadOnly db As String = "sql"
    ''' 
    ''' 实例化用户表类
    ''' 
    ''' 用户表类
    ''' 2011-3-23 9:57 by cjq
    Public Function CreateUserInfo() As IUserInfo
        Dim className As String = AssemblyName + "." + db + "UserInfo"
        Return CType(Assembly.Load(AssemblyName).CreateInstance(className), IUserInfo)
    End Function

接口层:

''' 
    ''' 检查一条记录
    ''' 
    ''' 一条记录
    ''' 是否存在这样一条记录
    ''' 2011-3-19 14:56 by cjq
    Function checkRecord(ByVal entityUserInfo As Entity.UserInfo) As Boolean
    ''' 
    ''' 返回一条记录
    ''' 
    ''' 一条记录
    ''' 一条用户记录
    ''' 2011-3-19 14:56 by cjq
    Function ReturnRecord(ByVal entityUserInfo As Entity.UserInfo) As Entity.UserInfo

数据持久层(在这里笔者参数传递可以换成存储过程):

在这里小论一下存储过程:

在程序逻辑中写SQL语句是很难处理复杂业务逻辑的,困难的引号匹配,复杂的字符串拼接过程,以及字符串拼接过程中的效率损失是我们不得不考虑的。

于是,处理复杂逻辑,如复杂的事务处理时,存储过程几乎成了唯一的方法。但是,存储过程一样有着他的致命缺点,就是他的移植性很差:当我们的项目更换数据库时,我们就要把存储过程完整地去拷贝到另外一个数据库,然后考虑他们的兼容问题;当我们修改数据层访问代码时,我们需要动的不再是应用程序服务器的代码,而是数据库端的代码,这是稍显痛苦的地方。(还是那句,没有完美的,只有最合适的)

''' 
    ''' 检查一条记录
    ''' 
    ''' 一记录
    ''' 是否存在这样一条记录
    ''' 2011-3-19 20:32 by lfsf802
Public Function checkRecord(ByVal entityUserInfo As Entity.UserInfo) As Boolean Implements Interfaces.IUserInfo.checkRecord
        Dim sql As String = "select * from UserInfo where userName=@userName"
        Dim conn As SqlConnection = New SqlConnection(connStr)
        Dim cmd As SqlCommand = New SqlCommand(sql, conn)
        Dim sqlParam As SqlParameter
        sqlParam = New SqlParameter("@userName", SqlDbType.VarChar)
        sqlParam.Value = entityUserInfo.UserName
        cmd.Parameters.Add(sqlParam)
        Dim sdr As SqlDataReader = Nothing
        Try
            conn.Open()
            sdr = cmd.ExecuteReader()
            sdr.Read()
            If (sdr.HasRows = True) Then
                Return True
            Else
                Return False
            End If
            'Return cmd.ExecuteNonQuery() > 0
        Catch ex As Exception
            Return False
        Finally
            If Not IsNothing(conn) Then
                conn.Close()
                conn = Nothing
            End If
            If Not IsNothing(cmd) Then
                cmd.Dispose()
                cmd = Nothing
            End If
        End Try
End Function
''' 
    ''' 返回一条用户信息记录
    ''' 
    ''' 一条用户信息
    ''' 一条用户信息记录
    ''' 2011-3-19 16:06 by lfsf802
    Public Function ReturnRecord(ByVal entityUserInfo As Entity.UserInfo) As Entity.UserInfo Implements Interfaces.IUserInfo.ReturnRecord
        Dim sql As String = "select * from UserInfo where userName=@userName"
        Dim conn As SqlConnection = New SqlConnection(connStr)
        Dim cmd As SqlCommand = New SqlCommand(sql, conn)
        Dim sqlParam As SqlParameter
        sqlParam = New SqlParameter("@userName", SqlDbType.VarChar)
        sqlParam.Value = entityUserInfo.UserName
        cmd.Parameters.Add(sqlParam)
        Dim sdr As SqlDataReader = Nothing
        Try
            conn.Open()
            sdr = cmd.ExecuteReader()
            While sdr.Read
                entityUserInfo.UserName = Trim(sdr.GetString(0))
                entityUserInfo.Password = Trim(sdr.GetString(1))
                entityUserInfo.StatusType = Trim(sdr.GetString(2))
                entityUserInfo.ComputerLabNo = Trim(sdr.GetInt32(3))
                entityUserInfo.TeacherName = Trim(sdr.GetString(4))
            End While
            Return entityUserInfo
        Catch ex As Exception
            Return Nothing
        Finally
            If Not IsNothing(conn) Then
                conn.Close()
                conn = Nothing
            End If
            If Not IsNothing(cmd) Then
                cmd.Dispose()
                cmd = Nothing
            End If
        End Try
    End Function

实体层(mapping数据库):

Public Class UserInfo
    Private _intComputerLabNo As Integer
    Private _strPassword As String
    Private _strStatusType As String
    Private _strTeacherName As String
    Private _strUserName As String
    ''' 
    ''' 机房号
    ''' 
    ''' 
    ''' 
    ''' 2011-3-14 15:26 by lfsf802
    Public Property ComputerLabNo() As Integer
        Get
            Return _intComputerLabNo
        End Get
        Set(ByVal value As Integer)
            _intComputerLabNo = value
        End Set
    End Property
    ''' 
    ''' 用户名
    ''' 
    ''' 
    ''' 
    ''' 2011-3-14 15:27 by lfsf802
    Public Property UserName() As String
        Get
            Return _strUserName
        End Get
        Set(ByVal value As String)
            _strUserName = value
        End Set
    End Property
    ''' 
    ''' 口令密码
    ''' 
    ''' 
    ''' 
    ''' 2011-3-14 15:28 by lfsf802
    Public Property Password() As String
        Get
            Return _strPassword
        End Get
        Set(ByVal value As String)
            _strPassword = value
        End Set
    End Property
    ''' 
    ''' 身份类型
    ''' 
    ''' 
    ''' 
    ''' 2011-3-14 15:29 by lfsf802
    Public Property StatusType() As String
        Get
            Return _strStatusType
        End Get
        Set(ByVal value As String)
            _strStatusType = value
        End Set
    End Property
    ''' 
    ''' 教师姓名
    ''' 
    ''' 
    ''' 
    ''' 2011-3-14 15:30 by lfsf802
    Public Property TeacherName() As String
        Get
            Return _strTeacherName
        End Get
        Set(ByVal value As String)
            _strTeacherName = value
        End Set
    End Property
End Class

飞了一回,你飞了吗?

分层,到这里就唠叨完了,不知道读者对三层有所了解?可以自己做一个小的demo试试哦!

分层,其实没有那么困难,关键是看思维能不能打开,能不能让自己飞起来,相信自己,飞一回试试!!!

最后:

没有完美的分层,只有适合项目工程的分层;但是你是完美的,要相信自己!

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics