您的位置:首页 > 其它

【机房重构】——加入外观、工厂和接口的三层

2016-03-13 20:59 176 查看



前言

  从传统的三层升七层,真的是拖了好长的时间揪其主要原因还是时间管理没有做好,其次就是个人的惰性。

  对于任何一个事物每个人都有不同的看法

  下面我就和大家说一下我从三层到七层的一个转变过程

  希望你也能找到一些同感

  如果理解和代码有不到位的,还请大牛斧正。

正文

总览

  所谓七层,就是在基本的三层中加入了外观和工厂模式,对应的加入了外观、接口和工厂。以及将原本的D层又抽象出了SqlHelper。

  附上一张盗的同学的七层的包图。



加入接口和工厂

  在升七层之前,死心眼的我一直在问:为什么要加入工厂?(那是不清楚接口要和工厂一起使用)

  问题了同期的同学,给我的答案基本上都是,为了换数据库啊!无奈我也只能就这么接受了。

  

  现有一个三层的登录例子(我最开始敲的)

  发现原本的D层UserDAO类代码写的不优雅,并且效率很差;想要更换成一个代码优雅的userDal

  那这个时候我们就必须对LoginBll类的代码进行一定的改动。

  


  通过设计模式的学习,我们显然的知道这不是一种好的解决方案。

  我们在追求的是更换D层UserDAO类时不更改B层任何代码,换句话说就是解除了B层和D层的耦合。

  因此我们加入了IDAL接口类库

  而此时在代码中,我们需要将B层原本对D层的引用更改为对IDAL的引用;

  在D层中也要增加对IDAL的引用。

  只要我们保证接口中方法的方法名不变,这样如何更换D层类,B层代码都不会受到影响

  


  那现在我还有问题,工厂是做什么的?不要它行不行?为什么偏偏叫做工厂?

  个人理解。

  在B层中调用接口

  1.接口不能实例化

  


  2.所以就必须为其赋初值

  


  


  3.为了解耦,就只能利用另一个类来给接口赋初值了

  4.至于工厂,也不过是个名字而已,工厂也只不过是个类的名字罢了,用不用都行,只是这样比较让大家好接受

  

  然后绕回来再说一句,为什么加工厂大家都说是为了换数据库?

  因为换数据库和上面说的是一回事,同样是换D层类。

加入外观

  在加外观之前就非常担心,感觉外观好难啊,我应该怎样加入到七层中呢?

  而将登录功能加上外观之后就感觉外观什么都没有。

  小U拿个东西给我,然后我想都不用想直接给小B就行了。

  

  感觉没有挑战性,就向注册窗体中加入外观。

  开始时是一样的。

  小U一个女生,背个大书包,而小B刚好受伤了拿不了东西。

  小B需要东西,只能我去拿,然后递给小B;后来小U累了,书包太大,还得停下来等我拿东西,出于责任感,我一个大男人多拿点东西也没有什么。

  现在小U轻松了,只需要将大书包给我,然后我拿着书包,小B需要东西,我直接给他就好了,不需要再去找小U了。

  

  而注册卡号就是这种情况,需要先验证再添加。

  之前是U层调外观调BU层调外观调B;现在是U层调外观,外观调B,外观调B。

  

  同样,像是有公主病的少女,有问题,我只找你,所有问题你必须解决。我只负责找你,其他的你去办就行了。

代码展示

  下面是登录窗体的代码展示

U层

Imports Facade
Imports Entity
Public Class frmLogin
Dim strUserID As String
Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
Dim user As New User_Info
user.UserID = txtUserID.Text.Trim
user.PassWord = txtPassWork.Text
Dim fac As New facLogin

txtPrompt.Text = fac.Test(user)
If txtPrompt.Text = "" Then
Me.Hide()
frmMain.Show()
End If
End Sub
End Class


外观

Imports BLL
Imports Entity
Public Class facLogin
Public Function Test(ByVal user As User_Info) As String
Dim Logbll As New LoginBll
Return Logbll.Test(user)
End Function
End Class


B层
Imports IDAL
Imports Entity
Imports Factory
Imports System.Data
Imports System.Data.SqlClient
Public Class LoginBll

Dim dt As New DataTable         REM 定义datatable对象
Dim log As ILogin               REM 定义接口对象,接口不能实例化
Dim fac As New Factory.factory  REM 实例化工厂

Public Function Test(ByVal user As User_Info) As String
REM 前面是一些简单的逻辑判断
If user.UserID = "" Then
Return "用户名不能为空"
End If

If user.PassWord = "" Then
Return "密码不能为空"
End If

log = fac.Logfactory             REM 接口不能实例化必须通过第三个类给接口赋初值
dt = log.selectUser(user)        REM 调用接口中的方法

Try
user.UserID = dt.Rows(0).Item(0)
user.Level = dt.Rows(0).Item(3)
log.AddWork(user)
Return ""
Catch ex As Exception
Return "用户名或密码错误"
End Try
End Function
End Class


接口

Imports Entity
Public Interface ILogin
Function selectUser(ByVal user As User_Info) As DataTable
Function AddWork(ByVal user As User_Info) As Integer
End Interface


D层

Imports System.Data
Imports System.Data.SqlClient
Imports SqlHelper
Imports Entity
Imports IDAL

Public Class SqlLoginDal : Implements ILogin
Public Function AddWork(user As User_Info) As Integer Implements ILogin.AddWork
Dim strLogindate As String = Date.Today
Dim strLogintime As String = TimeOfDay

Dim helper As New SqlHelper.sqlhelper

Dim cmdText As String = "INSERT INTO onwork_info VALUES (@userid,@level,@logindate,@logintime,@computer)"
Dim sqlParams As SqlParameter() = {New SqlParameter("@userid", user.UserID),
New SqlParameter("@level", user.Level),
New SqlParameter("@logindate", strLogindate),
New SqlParameter("@logintime", strLogintime),
New SqlParameter("@computer", Environment.GetEnvironmentVariable("COMPUTERNAME"))}
Return helper.ExecuteNonQuery(cmdText, CommandType.Text, sqlParams)
End Function

''' <summary>
''' 登录窗体检测用户名密码是否正确
''' </summary>
''' <param name="user"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function selectUser(user As User_Info) As DataTable Implements ILogin.selectUser
Dim strUserID As String = user.UserID
Dim strPassWord As String = user.PassWord
Dim cmdText As String = "SELECT * FROM user_info WHERE userid=@userid and password =@password"
Dim sqlParams As SqlParameter() = {New SqlParameter("@userid", strUserID), New SqlParameter("@password", strPassWord)}
Dim dt As New DataTable
Dim helper As New SqlHelper.sqlhelper
dt = helper.ExecuteQuery(cmdText, CommandType.Text, sqlParams)
Return dt
End Function
End Class


实体层

Public Class User_Info
Private _userid As String
Private _password As String
Private _username As String
Private _level As String
Private _head As String

Property UserID As String
Get
Return _userid
End Get
Set(value As String)
_userid = value
End Set
End Property

Property PassWord As String
Get
Return _password
End Get
Set(value As String)
_password = value
End Set
End Property

Property UserName As String
Get
Return _username
End Get
Set(value As String)
_username = value
End Set
End Property

Property Level As String
Get
Return _level
End Get
Set(value As String)
_level = value
End Set
End Property

Property Head As String
Get
Return _head
End Get
Set(value As String)
_head = value
End Set
End Property
End Class


总结

             任何事情,光是停留在想象上面,永远是困难的,犹如蜀道

     然而只要勇敢迈出第一步,又如探囊取物。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: