借着机房收费系统合作的机会,又把大话设计模式这本书拿了出来,我负责登录B层,就一直想着可以加什么设计模式。在第一次机房重构的时候,看着C#的代码写VB.NET一个星期才把三层敲完了,如今,在网上找了一个代理模式的例子,真是简单易懂啊。。学了这些东西之后,再返回来看设计模式,就是有不一样的感觉~
先来回顾一下什么是代理模式?还记得戴励追美眉的故事么?大家可以回想一下大话设计上的小故事。
代理模式的定义:
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理UML图解:
代理的好处:
1、分离业务逻辑与事务的处理。
2、添加一层中间层,起到保护目标对象的作用。
3、扩展性强,降低耦合度。
代理的缺点:
由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
什么时候需要用到代理模式:
1、客户端无法操作目标对象,在客户端建立一个远程对象的代理,这样在客户端操作远程对象,就像操作目标对象一样的效果。因为它们两个都实现了同一个接口。
2、除了当前此类的功能外,我们需要提供其他的功能。
图解代理模式(机房登录怎么用):
在登录的时候需要一个登录的事务,进行一大串的身份验证,其实登录就三部分:输入用户名和密码(U层验证是否为空)→验证身份→登录成功关闭连接。这个时候验证身份有好几个方法,我们就可以把一套事务写出来放到实现类里面,写一个代理接口,代理类,在U层直接调用我们的代理类就可以了。一行代码就够了。这样以来,U层就不用看到B层是如何实现的,因为它是直接面向代理类的,它不需要知道B层是如何实现的。
实战代理模式(登陆):
我们需要三个类,代理接口ILoginProxy,代理类LoginProxy,实现登录的B层Worklogbll。
<span style="font-size:18px;"><span style="font-size:18px;">Imports Entity Public Interface ILoginProxy Function TestUser(enUser As UserEntity) As List(Of UserEntity) End Interface </span></span>
<span style="font-size:18px;"><span style="font-size:18px;">Imports Entity Public Class LoginProxy : Implements ILoginProxy Dim worklogbll As New WorklogBLL Public Function TestUser(ByVal enUser As UserEntity) As List(Of UserEntity) Implements ILoginProxy.TestUser Return worklogbll.TestUser(enUser) End Function End Class </span></span>
<span style="font-size:18px;"><span style="font-size:18px;">'********************************************** ' 文 件 名:WorklogBLL ' 命名空间:BLL ' 内 容: ' 功 能: ' 文件关系: ' 作 者:周洲 ' 小 组:XX ' 生成日期:2015/5/14 11:28:16 ' 版 本 号:V1.0.0.0 ' 修改日志: ' 版权说明: '********************************************** Imports Entity Imports Factory Public Class WorklogBLL : Implements ILoginProxy Public facWork As New Factory.DataFactory '实例化工厂 Public facUser As New Factory.DataFactory '实例化工厂 Public iWork As IDAL.IWorklog = facWork.CreateWorklog '定义接口 Public iUser As IDAL.IUser = facUser.CreateUser '定义接口 ''' <summary> ''' 验证用户是否成功登陆的信息 ''' </summary> ''' <param name="enUser">传ID的User实体</param> ''' <returns></returns> ''' <remarks></remarks> Public Function TestUser(enUser As UserEntity) As List(Of UserEntity) Implements ILoginProxy.TestUser If iUser.Selectuserbyidpwd(enUser).Count > 0 Then If iWork.Userisonwork(enUser).Count > 0 Then '工作记录大于0,证明正在上机,先下机,再上机 enUser.Userlevel = iUser.Selectuserbyidpwd(enUser)(0).Userlevel iWork.Userupdatelogin(enUser) iWork.Userinsertlogin(enUser) Else '直接插入一条新的工作记录 enUser.Userlevel = iUser.Selectuserbyidpwd(enUser)(0).Userlevel iWork.Userinsertlogin(enUser) End If End If Return iUser.Selectuserbyidpwd(enUser) End Function</span></span>
<span style="font-size:18px;"> Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim enUser As New UserEntity Dim Userinfo As New List(Of UserEntity) enUser.UserID = "4" enUser.Pwd = "2" Dim iLoginProxy As ILoginProxy iLoginProxy = New LoginProxy Userinfo = iLoginProxy.TestUser(enUser) MsgBox(Userinfo(0).Userlevel) If Userinfo.Count > 0 Then FrmHomepage.Show() Me.Hide() If Userinfo(0).Userlevel.Trim() = "一般用户" Then FrmHomepage.一般用户ToolStripMenuItem.Enabled = True FrmHomepage.操作员ToolStripMenuItem.Enabled = False FrmHomepage.管理员ToolStripMenuItem.Enabled = False ElseIf Userinfo(0).Userlevel.Trim() = "操作员" Then FrmHomepage.一般用户ToolStripMenuItem.Enabled = True FrmHomepage.操作员ToolStripMenuItem.Enabled = True FrmHomepage.管理员ToolStripMenuItem.Enabled = False ElseIf Userinfo(0).Userlevel.Trim() = "管理员" Then FrmHomepage.一般用户ToolStripMenuItem.Enabled = True FrmHomepage.操作员ToolStripMenuItem.Enabled = True FrmHomepage.管理员ToolStripMenuItem.Enabled = True End If End If End Sub</span>
U层一句话就完成了登陆事务的处理,是不是很简单呀~
Userinfo = iLoginProxy.TestUser(enUser)
小结:
运用设计模式,就一个道理:想你不敢想的,就实现了~ 然后大胆的去做,我们总是否定着自己的想法,总觉得用什么设计模式都不合适吧,是不是太牵强了!其实,合作版机房就是一个练手的机会,大胆去想像就对了!只要你的立场坚定,我用某某设计模式就是为了解决哪个问题,就成功了!