敲完三层后,感觉还是对三层架构没有那么亲切,和小伙伴交流后,他们说多多敲几遍,就懂了,其实就是那么几条线,所以:不管会不会,先去做吧!

下面是关于七层的包图:

我的解决方案:

代码部分:

U层:

<span style="font-family:KaiTi_GB2312;font-size:18px;">Imports Login.Entity.UserEntity
Imports Facade
Imports System.Net.Dns Public Class FrmLogin
Private Sub btnOK_Click(sender As Object, e As EventArgs) Handles btnOK.Click
Dim strResult1 As Boolean
Dim strResult2 As Boolean
Dim FacadeLogin As New Facade.LoginFacade '定义一个外观对象
Dim UserInfo As New Login.Entity.UserEntity '定义一个实体类对象 '判断文本框
If txtUsername.Text = "" Then
MessageBox.Show("温馨提示,思密达输入用户名", "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
txtUsername.Text = "" '设置为空
txtUsername.Focus() '用户名获得焦点
Exit Sub
End If If txtPassword.Text = "" Then
MessageBox.Show("思密达,请输入密码", "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
txtPassword.Text = "" '设置为空
txtPassword.Focus() '密码框获得焦点
Exit Sub
End If Try '将文本框中的参数传递给实体
UserInfo.UserName = txtUsername.Text.Trim() '将用户名和密码赋值给实体类的对象UserinfoUserName;Password属性;
UserInfo.Password = txtPassword.Text.Trim() '从而Userinfo获取了U层的参数,通过外观层,传递到B层进行判断;
strResult1 = FacadeLogin.CheckUser(UserInfo) '将U层的用户名通过外观层传到B层,得到外观的返回值;
strResult2 = FacadeLogin.CheckPwd(UserInfo) If strResult1 = False Or strResult2 = False Then '通过返回值来判断用户是否存在;
MsgBox("用户名或密码不正确!")
txtUsername.Text = ""
txtPassword.Text = ""
txtUsername.Focus()
Else
MsgBox("登录成功!Amazing")
End If Catch ex As Exception
MsgBox("用户不存在或者密码不正确!")
txtUsername.Text = ""
txtPassword.Text = ""
txtUsername.Focus()
End Try
End Sub Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
Me.Close() '关闭窗体
End Sub Private Sub FrmLogin_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'获取计算机名称
Dim Address() As System.Net.IPAddress 'class system.net.IPAddress提供网际协议(IP)地址;
'class system.net.dns提供简单的域名解析功能;
'GetHostName()获取本地主机名;
'AddressList获取或设置与主机关联的IP列表;
Address = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList
txtComputer.Text = System.Net.Dns.GetHostName().ToString()
End Sub
End Class</span>

Façade层:

<span style="font-family:KaiTi_GB2312;font-size:18px;">Imports Login.Entity
Imports Login.BLL
Imports System.Reflection Public Class LoginFacade Public Function CheckUser(ByVal UserInfo As Login.Entity.UserEntity) As Boolean
Dim isUserExists As New Login.BLL.UserBLL() '实例化B层UserBLL类对象;
Dim flag As Boolean
flag = isUserExists.IsUserExists(UserInfo) '判断是否存在该用户
Return flag
End Function Public Function CheckPwd(ByVal UserInfo As Login.Entity.UserEntity) As Boolean
Dim isPwd As New Login.BLL.UserBLL() '实例化UserBLL对象;
Dim flag1 As Boolean
flag1 = isPwd.IsPwdRight(UserInfo) '判断userinfo对象的密码是否存在;
Return flag1
End Function
End Class</span>

B层:

<span style="font-family:KaiTi_GB2312;font-size:18px;">Public Class UserBLL
'检查用户是否存在
Public Function IsUserExists(ByVal UserInfo As Login.Entity.UserEntity) As Boolean
Dim Iuser As IDAL.IuserInfoDAL
'调用创建用户的工厂方法
Iuser = Factory.LoginFactory.CreateUserInfo
Dim table As DataTable
Dim flag As Boolean
table = Iuser.selectUser(UserInfo) '由于在sqlhelper中以表格的形式存在(adataset.Tables(0)),且开头第一列表示为0,所以Item(0)表示为用户名;
If table.Rows(0).Item(0) = 0 Then '第一行第一列
flag = False
Else
flag = True
End If
Return flag
End Function '查看密码是否正确
Public Function IsPwdRight(ByVal UserInfo As Login.Entity.UserEntity) As Boolean
Dim Iuser As IDAL.IuserInfoDAL
Dim table As DataTable '中间变量用来存储数据
Dim flag1 As Boolean
Iuser = Factory.LoginFactory.CreateUserInfo '调用工厂方法的Createuserinfo来创建iuser;
table = Iuser.selectUser(UserInfo) '调用接口的方法selectUser
If table.Rows(0).Item(0) = 0 Then
flag1 = False
Else
flag1 = True
End If
Return flag1
End Function
End Class</span>

Factory层:

为什么要用反射?

个人认为,接口本身没有没有具体实现,反射就是把接口的dll加载进内存,然后通过反射,实例化D层的类,调用dll方法。将B层的参数通过反射的方法, 在D层做具体实现。(仅供参考)

<span style="font-family:KaiTi_GB2312;font-size:18px;">Imports System.Configuration
Imports System.Reflection '使用反射来帮我们克服抽象工厂模式的先天不足
Imports Login.IDAL
Imports Login.DAL Public Class LoginFactory
'读配置文件,D层的每个类在配置文件里面对应一个key
'下面这句式把key变成变量,然后在下面这个方法中用这个变量就可以应用D层里面这个类了;
Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("DBString")
''' <summary>
''' ’实例化LoginDAL中users表中一个类
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function CreateUserInfo() As Login.IDAL.IuserInfoDAL
'CType是一个内联函数,将前面的部分转换为后半部分;
'LoginDAL为程序集名称;
'Login.DAL为命名空间名称;
'IuserInfoDAL 为要实例化的“类名”;
'CreateUserInfo ’创建实例;
Return CType(Assembly.Load("LoginDAL").CreateInstance("Login.DAL" & "." & "UserDAL"), IuserInfoDAL)
End Function
End Class</span>

接口层:

<span style="font-family:KaiTi_GB2312;font-size:18px;">Imports Login.Entity
Public Interface IuserInfoDAL
'UserInfo为用户的实体,是由实体类实例化而来的
'即所谓的传实体
'此接口定义了一个方法,用来检测用户是否存在
Function selectUser(ByVal UserInfo As Login.Entity.UserEntity) As DataTable
End Interface</span>

D层:

<span style="font-family:KaiTi_GB2312;font-size:18px;">Imports System.Data.SqlClient
'system.data.sqlClient命名空间是SQL SERVER的.netframework数据提供的程序
'sql server的.net framework数据提供程序描述了一个类集合,这个类用于访问托管中的sql server数据库;
Imports Login.Entity
Imports Login.IDAL
Imports SQLHelper Public Class UserDAL : Implements IDAL.IuserInfoDAL '实现接口中的方法;
'声明并实例化sqlhelper类
Private SqlHelper As SQLHelper.sqlhelper = New SQLHelper.sqlhelper
Public Function selectUser(UserInfo As Login.Entity.UserEntity) As DataTable Implements IuserInfoDAL.selectUser
Dim Sql As String
Dim table As DataTable '中间变量用于存储从数据库中查找信息
Dim sqlConnectStr As String = "server =ZLT;database=Login;uid=sa;pwd=123"
'声明并实例化参数数组
Dim sqlParams As SqlParameter() = {New SqlParameter("@UserName", UserInfo.UserName), New SqlParameter("@Password", UserInfo.Password)}
Sql = "select * from Users where UserName=@UserName and Password=@Password" 'SQL是查询到的信息;
'下句为调用SqlHelper类中的GetDataTable()方法来执行查询,并获取返回值;
table = SqlHelper.GetDataTable(Sql, CommandType.Text, sqlParams)
Return table
End Function
End Class</span>

Entity层:

<span style="font-family:KaiTi_GB2312;font-size:18px;">Public Class UserEntity

    '区别变量的名字,变量的名字比数据库多“_”
Private _UserName As String
Private _Password As String
Private _UserID As String
Private _level As String
Private _Holder As String '以下为可读写属性,名字和数据库中的一样
Public Property UserName() As String
Get
Return _UserName
End Get
Set(value As String)
_UserName = value
End Set
End Property Public Property Password() As String
Get
Return _Password
End Get
Set(value As String)
_Password = value
End Set
End Property
End Class</span>

SQLHelper层:

为什么要用SQLHelper?

Sqlhelper封装了对数据库的增删改查,所以减少了代码的量,提高了系统性能;具体见:点我

<span style="font-family:KaiTi_GB2312;font-size:18px;">Imports System.Data.SqlClient
Imports System.Configuration
Imports System.Data
Imports System.Reflection Public Class sqlhelper
'configurationManager表示读配置文件;
'appsetting获取配置文件的数据;
Public Shared ConnectionString As String = ConfigurationManager.AppSettings("sqlConnectStr")
'sqlDataAdapter表示用于填充Data.Dataset和更新SQL SERVER数据库的一组数组命令和一个数据库连接;
Private Shared Property adaptor As SqlDataAdapter
'''<summary>
'''执行带参数的查询操作
'''</summary>
''' <param name="cmdTxt">参数cmdTxt为所要执行的sql语句</param>
''' <param name="cmdType">查询时的查询方式</param>
''' <param name="paras">查询时的命令参数paras</param>
''' <returns>查询后以表示的方式返回,如下面adataset.Tables(0)</returns>
''' <remarks></remarks>
Public Shared Function GetDataTable(ByVal cmdTxt As String, ByVal cmdType As CommandType, ByVal paras As SqlParameter()) As DataTable
Dim conn As SqlConnection = New SqlConnection(ConnectionString) '建立数据库连接;
Dim cmd As SqlCommand '定义命令变量;
Dim adaptor As SqlDataAdapter '定义数据库适配器;
Dim adataset As DataSet '定义并实例化数据库缓冲区对象,即从数据库传入对象;
cmd = New SqlCommand(cmdTxt, conn) '在Conn上实例化命令变量,并执行cmdType;
cmd.CommandType = cmdType '执行命令的类型
cmd.Parameters.AddRange(paras) '命令执行时的参数
adaptor = New SqlDataAdapter(cmd) '将结果绑定到数据库适配器变量adaptor上面;
adataset = New DataSet 'dataset表示数据内存中缓存;
Try
'如果数据库连接状态为关闭则将其打开;
If conn.State = ConnectionState.Closed Then
conn.Open()
End If
adaptor.Fill(adataset) '向adaptor对象中填充要查询的数据;
Catch ex As Exception
'错误处理程序,出错则提示
MsgBox(ex.Message, , "数据库操作!")
Finally
'如果连接状态为打开,则将其关闭,释放内存;
If conn.State = ConnectionState.Open Then
conn.Close()
End If
End Try
'以表格的形式返回结果
Return adataset.Tables(0)
End Function
Function GetDataTable() As DataTable
Throw New NotImplementedException
End Function
End Class</span>

生成依赖项关系图:


小结:

这个阶段总是在参考别人的博客学习,学到了很多东西,自己也亲自调试了好多错误(具体错误:点我),成长了好多,在以后机房重构的过程中,希望自己多多实践自己的想法。

1、  站在巨人的肩膀上学习,让我们知道了许多以前不知道的地方;

2、  代码如人生,重要的不是代码,而是思想。

感谢您的宝贵时间~~~

七层登录——VB.NET版的更多相关文章

  1. 三层登录——VB.NET版

    前言 由于下面的机房收费系统重构自己要用VB.NET进行重构,所以在敲三层登录的时候,实践了一份C#版三层登录,接着就是VB.NET版的三层登录.话说还有七层登录,一下子感觉三层又矮小了.万丈高楼平地 ...

  2. VB.NET版机房收费系统---七仙女之系统登录

    VB.NET第一版机房收费系统,告一段落,验收的时候.问题也是大大的存在,没实用上设计模式,什么触发器.存储过程,都没实用上.看看其她小伙伴的,七层实现登录?那是什么东东,相比較我的三层而言,多了两倍 ...

  3. vb.net版机房收费——助你学会七层架构(一)

    我自己写机房的时候,看非常多高人的博客,各种的借鉴,当初务必的纠结,如今整个机房敲完了,写这篇博客给大家一个总体上的.简单理解的七层,期望大家看完这篇文章之后,不会这个纠结了. 首先大家得看了我的上一 ...

  4. 三层——vb.net版

    经过不懈的努力,我的vb.net 版的三层登陆终于实现了.下面将我的成果向大家展示一下. 原则          vb.net的三层登陆跟C#的三层登陆的思想是一样的都是将系统分层--U层只负责与用户 ...

  5. TCP/IP协议(一)网络基础知识 网络七层协议

    参考书籍为<图解tcp/ip>-第五版.这篇随笔,主要内容还是TCP/IP所必备的基础知识,包括计算机与网络发展的历史及标准化过程(简述).OSI参考模型.网络概念的本质.网络构建的设备等 ...

  6. OSI七层模型详解 TCP/IP协议

      总结 OSI中的层 功能 TCP/IP协议族 应用层 文件传输,电子邮件,文件服务,虚拟终端 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 等等 表示层 数据格式化,代码转 ...

  7. python网络编程-OSI七层模型详解

    OSI 七层模型通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯,因此其最主要的功能就是帮助不同类型的主机实现数据传输 . 完成中继功能的节点通常称为中继系统.在OSI七层模型中,处于 ...

  8. OSI七层模型

    OSI 七层模型通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯,因此其最主要的功能就是帮助不同类型的主机实现数据传输 . 完成中继功能的节点通常称为中继系统.在OSI七层模型中,处于 ...

  9. 网络知识学习1---(基础知识:ISO/OSI七层模型和TCP/IP四层模型)

    以下的内容和之后的几篇博客只是比较初级的介绍,想要深入学习的话建议自己钻研<TCP/IP详解 卷1:协议> 1.ISO/OSI七层模型    下四层是为数据传输服务的,物理层是真正的传输数 ...

随机推荐

  1. java:eclipse安装tomcat插件及配置tomcat

    我们都知道myeclipse自带tomat图标,而eclipse却没有,若想eclipse实现带有tomcat图标可以下载tomcat插件 tomcat插件下载地址:http://www.eclips ...

  2. IIS 高并发导致log记录不完全

    项目测试性能过程中,对于高并发测试过程中发现log记录缺失一部分,经过调查,找到了原因是因为IIS连接数的限制,经过修改连接数,成功完成.设置如下: “点击网站”->“右击切换到功能视图”-&g ...

  3. cudnn 卷积例子

    运行环境:linux cuda cudnn cudnn API:https://docs.nvidia.com/deeplearning/sdk/cudnn-developer-guide/index ...

  4. 2017-2018-1 20179203 《Linux内核原理与分析》第三周作业

    攥写人:李鹏举 学号:20179203 ( 原创作品转载请注明出处) ( 学习课程:<Linux内核分析>MOOC课程http://mooc.study.163.com/course/US ...

  5. ACM学习历程—UESTC 1226 Huatuo's Medicine(数学)(2015CCPC L)

    题目链接:http://acm.uestc.edu.cn/#/problem/show/1226 题目就是构造一个对称的串,除了中间的那个只有1个,其余的两边都是对称的两个,自然答案就是2*n-1. ...

  6. UML Design Via Visual Studio-Sequence Diagram

    本文主要介绍在Visual Studio中设计时序图,内容如下: 何时使用时序图 时序图元素介绍 条件.循环在时序图中的使用 直接通过代码生成时序图 一.何时使用时序图 当要查看单个用例内若干对象的行 ...

  7. android开发 解析服务器端xml文件数据存储到android客户端SQLite数据库

    以下面xml文件为例对其解析(假设此xml就在服务器端Server项目下的servlet包下的MenuServlet文件的输出流中): <?xml version="1.0" ...

  8. C# 表达式树(Expression)

    c#中有Expression,即表达式. 通过Expression可以动态构造代码,并编译执行.  比如: 1.  创建参数表达式 :ParameterExpression numParam = Ex ...

  9. 有关HL7 的C# 源码

    https://github.com/OSEHRA/mdo              C# http://sourceforge.net/p/nhapi/code/HEAD/tree/NHapi20/ ...

  10. 人物-IT-柳传志:柳传志

    ylbtech-人物-IT-柳传志:柳传志 柳传志,英文名:Chuanzhi Liu,男,汉族,中共党员,1944年4月出生于江苏镇江,联想控股股份有限公司董事长,联想集团创始人. 企业家.投资家.全 ...