三层的优化(七层架构)

来源:互联网 发布:苹果7蜂窝移动数据 编辑:程序博客网 时间:2024/06/11 17:59

    上篇文章中介绍了简单的三层架构(U层、B层和D层),三层架构能同过业务逻辑层(B层)作为中间层,对表示层(U层)和数据访问层(D层)进行“解耦”。三层之间各司其职,互不影响,从而保证了系统的正常运行。

    简单三层架构虽然解除了U层和D层的耦合,可是U层和B层,B层和D层都有很高的耦合。那么,能否对三层进行进一步的解耦呢?答案是肯定的,之间学习过的设计模式就能很好地解决这个问题。先来一张包图,看看加入设计模式的三层有何变化。

    

    由包图可以看出,原先的三层在U层和B层之间加上外观类解除之间的耦合,B层和D层之间加上工厂类和接口解除他们之间的耦合,从而由三层架构优化成七层架构。下面详细地介绍七层架构在VB.Net环境下的实现(以登录窗体为例)。

    U层+外观模式+B层

    外观类封装B层中各个类的方法或者属性,在U层中只需要实例化外观类的实体,通过实体去调用B层的类,解除了U层和B层之间的耦合。 

    外观类

Public Class FacadeLogin '外观类,解除U层和B层的耦合,外观类中包含B层对D层的所有操作    Dim manager As Login.BLL.LoginManager = New Login.BLL.LoginManager() '实例化B层中的类LoginManager    Public Sub Login(ByVal user As Login.Entity.Userinfo)        manager.UserLogin(user)    End SubEnd Class
    U层   

Public Class Form1                                                                      'U层调用外观类,通过外观类访问B层中的所有方法。    Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click        'Dim manager As Login.BLL.LoginManager = New Login.BLL.LoginManager()        Dim user As Login.Entity.Userinfo = New Login.Entity.Userinfo()        Dim facade As Facade.FacadeLogin = New Facade.FacadeLogin()                     '实例化外观类        user.UserName = txtUserName.Text                                                '通过文本框给实体赋值        user.Password = txtPassword.Text        facade.Login(user)        'manager.UserLogin(user)        MessageBox.Show("登录成功" + user.UserName)    End Sub
    有了外观类,U层不需要去实例化B层中类,间接地去使用B层中的类。试想一下,B层中有100个类,如果没有外观类的存在,U层就需要去实例化100个B层类的实体,根据“高内聚,低耦合”的原则,这是绝对不允许的。

    B层+抽象工厂+D层

    工厂+接口解除了B层和D层之间的耦合。工厂中创建接口类,其返回值是D层中实现类。关于这一部分我的理解是把接口类看做父类,实现类看做子类。子类以父类的身份出现,但工作时以自己的方式来实现,也就是多态。B层只与工厂类和接口类交互,通过工厂类创建出D层中的实现类,间接的使用。这样就很好地解除了B层和D层之间的耦合。

   工厂类

Imports System.Reflection                                       '引用反射机制Public Class usersql    Dim user As IUser.UserSQL                                   '声明变量,其类型是IUser.UserSQL     Public Function createuser() As IUser.UserSQL        user = CType(Assembly.Load("LoginDAL").CreateInstance("Login.DAL.UserDAO"), IUser.UserSQL) '返回userDao类        Return user    End FunctionEnd Class
             接口

Public Interface UserSQL                '声明接口的关键字Interface    Function SelectUser(ByVal user As Login.Entity.Userinfo) As Login.Entity.Userinfo '接口中的方法需要D层中类去实现。End Interface
             D层

Public Class UserDAO : Implements IUser.UserSQL         '关键字implements,表明去实现接口    Public Function SelectUser(ByVal user As Login.Entity.Userinfo) As Login.Entity.Userinfo Implements IUser.UserSQL.SelectUser <span style="white-space:pre"></span>'实现接口的方法        Dim cn As SqlConnection = Login.DAL.DbUtil.connString()                                                           <span style="white-space:pre"></span>'连接数据库        Dim sql As String = "SELECT ID,UserName,Password,Email FROM USERS WHERE UserName =@UserName AND Password =@Password"    '定义SQL语句        Dim cmd As SqlCommand = New SqlCommand(sql, cn)        cmd.Parameters.Add(New SqlParameter("@UserName", user.UserName))        cmd.Parameters.Add(New SqlParameter("@Password", user.Password))        cn.Open() '打开数据库        Dim reader As SqlDataReader = cmd.ExecuteReader()        Dim Buser As Login.Entity.Userinfo = New Login.Entity.Userinfo()        While (reader.Read())            Buser.UserName = reader.GetString(1)            Buser.Password = reader.GetString(2)        End While        Return Buser    End Function

    B层  

Public Class LoginManager                                           'B层引用工厂类和接口类    Public Function UserLogin(ByVal user As Login.Entity.Userinfo) As Login.Entity.Userinfo        Dim Uuser As Login.Entity.Userinfo = New Login.Entity.Userinfo()        Dim score As Login.Entity.Scores = New Login.Entity.Scores()        Dim factory = New IFactory.usersql()            '实例化工厂        Dim iu = factory.createuser()                   '变量iu为D层UserDao实体        Uuser = iu.SelectUser(user)        If (Not IsDBNull(Uuser)) Then            score.Scores = 20            Dim sc As Login.DAL.ScoreDAO = New Login.DAL.ScoreDAO()            sc.Update(Uuser, score)        Else            Throw New Exception("登录失败")        End If        Return Uuser    End Function<span style="font-family: KaiTi_GB2312; background-color: rgb(255, 255, 255);">        </span>

     配置文件的使用。利用配置文件,可以很方便地更换数据库。配置文件建立在U层中。

<configuration>    <startup>        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />    </startup>  <appSettings>  <add key="Str" value="Server=.; Database=Login; User ID=sa; Password=123456"/>’连接数据库字符串    </appSettings>  <appSettings>    <add key="DBString" value ="Sql"></add>'指明系统用到的数据库是SQL Server  </appSettings></configuration>

   总结

   三层的优化使我对面向对象编程有了一定的理解,尤其是各层之间参数的传递。之前对参数的理解仅仅是一个变量,经过这次三层的学习才知道这个变量其实是实体。各层之间通过实体的传递进行交互,从而有效地使各层之间的耦合降低。

   PS:外观类虽然解除了U层和B层的耦合,可是外观类和B层却存在强耦合。它们两者之间的耦合降低的话也是用工厂+接口实现,大家不妨做一下。

    

     

2 0
原创粉丝点击