您的位置:首页 > 其它

登陆也需要装饰——机房收费系统装饰模式实战

2013-05-05 11:35 253 查看
一、装饰模式概述

装饰模式的用途,顾名思义,现实生活中我们需要一些装饰品来装饰人,或者物。淡然没有这些装饰,物体和人依然是存在的,这就意味着装饰品并非必须的,我们有时需要一个(项链),或许有时需要二个(项链,耳钉),再或者需要更多(项链,耳钉,戒指……),用一句话概括:装饰模式就是动态地给一个对象添加一些额外的职责

关于更多装饰模式理论:详见博客:装饰模式——结构型设计模式之四



二、用户装饰模式来装饰机房收费系统登陆

任何一个系统登陆都需要经过验证,这里以机房收费系统为例进行说明。

首先登陆到一个系统,为了系统安全性,我们应该从用户名,密码,来考虑。

登陆系统时需要提供匹配的用户名和密码,然后通过系统的验证通过后,方可登陆成功。

先要验证用户名,是否存在,然后验证用户密码是否正确,如果有登陆状态,最后验证登陆状态是否可以登陆。

在这里,我们可以把用户名,密码,登陆状态看成四对“登陆这个对象”的装饰,使用装饰模式。

先看装饰模式的类图:



然后结合登陆使用的装饰模式图如下:





这里省略掉了接口:component。因为这里的concreteComponent只有“login ”,所以没有必要在定义一个接口。我们让TestUser 继承Login 类,其实,TestUser ,也不可以不继承Login ,这样,“Login ”和TestUser 之间就是关联关系,也可以实现。

具体代码实现:

Login类的如下:定义了一个抽象方法



Public MustInherit Class Login

    ''' <summary>
    ''' 检测用户是否可以登陆
    ''' </summary>
    ''' <param name="useren">用户类</param>
    Public MustOverride Function TestLogin(ByVal useren As UserEntity) As Boolean

End Class


TestUser 类如下;

''' <summary>
''' 检测用户类_继承自login 类
''' </summary>
Public MustInherit Class TestUser
    Inherits Login
    Public declogin As Login
    ''' <summary>
    ''' 设定要装饰的对象
    ''' </summary>
    ''' <param name="declogin"></param>
    ''' <remarks></remarks>
    Public Sub SetObject(ByVal declogin As Login)
        Me.declogin = declogin
    End Sub

    ''' <summary>
    ''' 检测用户是否可以登陆
    ''' </summary>
    ''' <param name="useren">用户类</param>
    Public Overrides Function TestLogin(ByVal useren As UserEntity) As Boolean
        '定义返回值
        Dim flag As Boolean = False
        '如果要装饰的对象不为空,就调用装饰方法
        If Not (declogin Is Nothing) Then
            flag = declogin.TestLogin(useren)
        End If
        Return flag
    End Function

End Class  ' TestUser


三个装饰类:

''' <summary>
''' 判断用户是否存在
''' </summary>
Public Class UserExist
    Inherits BLL.TestUser
    ''' <summary>
    ''' 检测用户是否可以登陆_用户是否存在
    ''' </summary>
    ''' <param name="useren">用户类</param>
    Public Overrides Function TestLogin(ByVal useren As UserEntity) As Boolean
        '定义返回值
        Dim flag As Boolean = False
        Dim af As AbstractFactory.AbstractFactory = AbstractFactory.AbstractFactory.GetInstance()
        Dim iuser As IDAL.IUser
        '创建接口库
        iuser = af.CreateUser()
        If Not (iuser.QueryUserInfo(useren) Is Nothing) Then
            flag = True
        Else
            Throw New Exception("用户名不存在,请检查用户名,重新登陆。")
        End If
        Return flag
    End Function
End Class ' UserExist




''' <summary>
''' 验证密码是否正确
''' </summary>
Public Class TestPwd
    Inherits BLL.TestUser
    ''' <summary>
    ''' 检测用户是否可以登陆_检测密码
    ''' </summary>
    ''' <param name="useren">用户类</param>
    Public Overrides Function TestLogin(ByVal useren As UserEntity) As Boolean
        '定义返回值
        Dim flag As Boolean = False
        Dim af As AbstractFactory.AbstractFactory = AbstractFactory.AbstractFactory.GetInstance()
        Dim iuser As IDAL.IUser
        '创建接口库
        iuser = af.CreateUser()
        If iuser.QueryUserInfo(useren).P_password = useren.P_password Then
            flag = True
        Else
            Throw New Exception("登陆密码不正确,请重新输入。")

        End If
        Return flag
    End Function
End Class ' TestPwd




''' <summary>
''' 查询用户状态
''' </summary>
Public Class UserState
    Inherits TestUser
    ''' <summary>
    ''' 检测用户是否可以登陆——查询用户状态
    ''' </summary>
    ''' <param name="useren">用户类</param>
    Public Overrides Function TestLogin(ByVal useren As UserEntity) As Boolean
        '定义返回值
        Dim flag As Boolean = False
        Dim af As AbstractFactory.AbstractFactory = AbstractFactory.AbstractFactory.GetInstance()
        Dim iuser As IDAL.IUser
        '创建接口库
        iuser = af.CreateUser()
        If iuser.QueryUserInfo(useren).P_userstatus = "离线" Then
            flag = True
        Else
            Throw New Exception("用户已经在线,不可以重复登陆。")
        End If
        Return flag
    End Function
End Class ' UserState


主要的类都写完了,接下来就是客户端的调用了,

在调用是,根据装饰模式的特性,我们需要循环嵌套调用,为了使装饰的东西先后顺序稳定,

''' <summary>
    ''' 用户登陆系统方法
    ''' </summary>
    ''' <param name="useren">要登陆的用户实体</param>
    Public Function Login(ByVal useren As UserEntity, worklogen As WorkLogEntity) As Boolean
        Dim flag As Boolean = False
        '判断用户是否存在
        Dim Bqueryuser As New BLL.QueryUser
        '定义登陆变量,存放用户登陆的几种情况
        'Dim intLogin As Int32
        'intLogin = Bqueryuser.UserInfo(useren)
        '判断登陆的情况
        '****************************?????考虑使用迭代器模式
        '使用装饰模式
        '定义B层装饰模式对象
        Dim Blogin As BLL.Login
        '装饰对象声明
        Dim BuserState As New BLL.UserState()
        Dim BtestPWD As New BLL.TestPwd()
        Dim BuserExist As New BLL.UserExist()
        'Dim BtestUser As BLL.TestUser
        '装饰过程
        '4/声明验证对象
        BuserState.SetObject(Blogin)
        '3状态验证
        BtestPWD.SetObject(BuserState)
        '2密码验证
        BuserExist.SetObject(BtestPWD)
        '1验证用户是否存在
        '验证全部通过,然后修改用户状态和插入工作记录
        If BuserExist.TestLogin(useren) Then
            '调用B层方法
            If Buser.UpdateUserState(useren) Then
                '声明工作记录对象
                Dim Bworklog As New BLL.WorkLog
                '调用B层方法
                If Bworklog.AddWorkLog(worklogen) Then
                    '插入记录成功返回真
                    flag = True
                    Throw New Exception("用户登陆成功,马上跳转到主界面!")
                End If
            End If
        End If
        Return flag
    End Function

通过以上的叙述,装饰模式就结束了。

如果用户需求发生变化,你需要增加价差,或者减少检查,只需要增加/去掉相应类即可,然后再客户端中修改调用对象即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: