装饰模式,动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
它是为已有功能动态添加更多功能的一种方式。当系统添加新功能的时候,是向旧的类中添加新的代码。这些想你加的代码通常装饰了原有类的核心职责或主要行为。他们就在主类中加入了新的字段,新的方法和逻辑,从而增加了主类的复杂度。
为了能够更了解装饰模式,在设计机房收费系统的时候,将装饰模式用在了用户登录的逻辑中。用户登录的时候首先判断用户是否存在,然后判断用户输入的密码是否正确,最后判断用户是否已经在线。经过三层判断之后用户才能上线。为了方便演示我对登录界面做了修改。
1界面展示
2代码展示
''' <summary> ''' 用户登录窗体 ''' </summary> ''' <remarks></remarks> Public Class frmLogin ''' <summary> ''' 单击窗体中的确定按钮 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click Dim UserLoginMain As New UserLogin '定义了一个封装了装束顺序的类,调用此类并将参数传入 UserLoginMain.UserLoginMain(txtUserName.Text, txtPassword.Text, lblState.Text) End Sub ''' <summary> ''' 加载登录窗体 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub frmLogin_Load(sender As Object, e As EventArgs) Handles MyBase.Load dataState.Items.Add("上机") dataState.Items.Add("下机") End Sub End Class
''' <summary> ''' 调用类,将客户端的任务和装饰顺序封装在此类中 ''' </summary> ''' <remarks></remarks> Public Class UserLogin Public Sub UserLoginMain(ByVal UExist As String, ByVal UPassword As String, ByVal UOnduty As String) Dim LoginMian As New Login '定义登录的具体的类,相当于《大话设计》中装饰模式的人 Dim DecorateTestExist As New TestExist '具体的装饰类---判断用户是否存在 Dim DecorateTestPassword As New TestPassword '具体的装饰类,判断密码是否正确 Dim DecorateTestState As New TestState '具体的装饰类,判断用户的状态。 '装饰过程 DecorateTestState.Decorate(LoginMian) DecorateTestPassword.Decorate(DecorateTestState) DecorateTestExist.Decorate(DecorateTestPassword) DecorateTestExist.TestLogin(UExist, UPassword, UOnduty) End Sub End Class
''' <summary> ''' 登录的具体的类,相当于《大话设计》中装饰模式的人 ''' </summary> ''' <remarks></remarks> Public Class Login 'Public Overrides Sub TestLogin(ByVal UExist As String, ByVal UPassword As String, ByVal UOnduty As String) ' frmLogin.Hide() 'End Sub Public Overridable Sub TestLogin(ByVal UExist As String, ByVal UPassword As String, ByVal UOnduty As String) frmMain .Show frmLogin.Hide() End Sub End Class
Public Class TestUser : Inherits Login Protected declogin As Login '定义该类的保护属性 ''' <summary> ''' 装饰的方法 ''' </summary> ''' <param name="declogin"></param> ''' <remarks></remarks> Public Sub Decorate(ByVal declogin As Login) Me.declogin = declogin End Sub ''' <summary> ''' 虚方法,判断用户是否能够登录 ''' </summary> ''' <param name="UExist">用户名</param> ''' <param name="UPassword">密码</param> ''' <param name="UOnduty">用户状态</param> ''' <remarks></remarks> Public Overrides Sub TestLogin(ByVal UExist As String, ByVal UPassword As String, ByVal UOnduty As String) '如果要装饰的对象不为空,就调用装饰方法 If Not (declogin Is Nothing) Then declogin.TestLogin(UExist, UPassword, UOnduty) End If End Sub End Class
Public Class TestExist : Inherits TestUser ''' <summary> ''' 重写父类方法,判断用户是否存在 ''' </summary> ''' <param name="UExist"></param> ''' <param name="UPassword"></param> ''' <param name="UOnduty"></param> ''' <remarks></remarks> Public Overrides Sub TestLogin(ByVal UExist As String, ByVal UPassword As String, ByVal UOnduty As String) If Trim(UExist) = Trim(frmLogin.dataUserName.Text) Then MyBase.TestLogin(UExist, UPassword, UOnduty) Else MsgBox("用户不存在", , "提示") End If End Sub End Class
Public Class TestPassword : Inherits TestUser ''' <summary> ''' 重写父类方法,判断密码是否正确 ''' </summary> ''' <param name="UExist"></param> ''' <param name="UPassword"></param> ''' <param name="UOnduty"></param> ''' <remarks></remarks> Public Overrides Sub TestLogin(ByVal UExist As String, ByVal UPassword As String, ByVal UOnduty As String) If UPassword = frmLogin.dataPassword.Text Then MyBase.TestLogin(UExist, UPassword, UOnduty) Else MsgBox("密码不正确", , "提示") End If End Sub End Class
Public Class TestState : Inherits TestUser ''' <summary> ''' 重写父类方法,判断用户是否已经登录 ''' </summary> ''' <param name="UExist"></param> ''' <param name="UPassword"></param> ''' <param name="UOnduty"></param> ''' <remarks></remarks> Public Overrides Sub TestLogin(ByVal UExist As String, ByVal UPassword As String, ByVal UOnduty As String) If Trim(frmLogin.dataState.Text) = Trim(frmLogin.lblState.Text) Then MyBase.TestLogin(UExist, UPassword, UOnduty) Else MsgBox("用户在上机", , "提示") End If End Sub End Class