从文本框限制字符输入,理解代码抽象过程(四次抽象到简单工厂到反射)

这里写目录标题

  • 背景
  • 原因
  • 抽象过程
    • 第一次抽象
    • 第二次抽象
    • 第三次抽象
    • 第四次抽象
    • 简单工厂
    • 反射

背景

    学生信息管理系统中有很多文本框的校验,其中有一点,就是不允许输入过长的信息。

原因

1、文本框校验限制输入长度确保用户内容不超出系统或数据库容量限制,避免数据溢出和系统性能下降。
2、限制输入长度有助于节省服务器和数据库资源,避免长篇文本消耗过多存储和计算资源。
3、提高系统性能和响应速度是限制输入长度的目的之一。
4、限制输入长度可以减少用户输入错误和不必要的长篇内容,提升用户体验。
5、短文本相比长文本在网络传输时更加高效,减少带宽和传输时间,节省网络流量和传输延迟。

抽象过程

第一次抽象

先来看代码

Public Sub LimitTextBoxLength(txtBox As TextBox, maxLength As Integer)
'限制文本框长度If Len(txtBox.Text) > maxLength ThentxtBox.Text = Left(txtBox.Text, maxLength)MsgBox "请输入内容少于 " & maxLength & " 个字符。"End If
End Sub

    这种做法就是将用户输入的内容截取成限制的字符长度,比如限制的字符长度为10,用户输入100个字符,输入结束,一点回车,直接被截成10个字符,用户会心里说一句“逗我玩呢”,这种多少有些不尊重用户,用户体验感极差。
后面根据需求更改了代码

第二次抽象

这版还增加了一点功能,对输入内容进行限制

Private Sub txtName_keypress(keyAscii As Integer)' 允许汉字、字母、数字、空格If Not ((keyAscii >= -20319 And keyAscii <= -3652) Or (keyAscii >= 48 And keyAscii <= 57) Or (keyAscii >= 65 And keyAscii <= 90) Or (keyAscii >= 97 And keyAscii <= 122) Or keyAscii = 32 Or keyAscii = 8) ThenkeyAscii = 0MsgBox "您输入的不是有效字符", 0, "温馨提示"End If' 判断名字长度If (Len(txtName.Text) > 10) ThenMsgBox "姓名字符太长", 0, "温馨提示"txtName.SetFocustxtName.Text = ""Exit SubEnd If
End Sub

这段代码是对输入学生信息时,姓名文本框的限制
在这里插入图片描述
    然后发现除了姓名文本框需要限制,学号也需要限制,就想把这段代码抽出来复用,要实现代码的复用,可以将这段逻辑封装成一个通用的函数,然后在每个文本框的 KeyPress 事件中调用这个函数。

第三次抽象

首先,创建一个新的模块(Module),在其中定义一个通用的函数,用于检查输入字符的有效性和长度限制:

Public Function CheckInputValidity(txtBox As Object, keyAscii As Integer, maxLength As Integer) As Boolean' 允许汉字、字母、数字、空格If Not ((keyAscii >= -20319 And keyAscii <= -3652) Or (keyAscii >= 48 And keyAscii <= 57) Or (keyAscii >= 65 And keyAscii <= 90) Or (keyAscii >= 97 And keyAscii <= 122) Or keyAscii = 32 Or keyAscii = 8) ThenkeyAscii = 0MsgBox "您输入的不是有效字符", 0, "温馨提示"CheckInputValidity = FalseExit FunctionEnd If' 判断字符长度If (Len(txtBox.Text) > maxLength) ThenMsgBox txtBox.Name & " 字符太长", 0, "温馨提示"txtBox.SetFocustxtBox.Text = ""CheckInputValidity = FalseExit FunctionEnd IfCheckInputValidity = True
End Function

然后,在每个文本框的 KeyPress 事件中调用这个通用函数,例如:

Private Sub txtName_KeyPress(KeyAscii As Integer)Dim isValidInput As BooleanisValidInput = CheckInputValidity(txtName, KeyAscii, 10)If Not isValidInput ThenKeyAscii = 0End If
End SubPrivate Sub txtAnotherTextBox_KeyPress(KeyAscii As Integer)Dim isValidInput As BooleanisValidInput = CheckInputValidity(txtAnotherTextBox, KeyAscii, 20)If Not isValidInput ThenKeyAscii = 0End If
End Sub

    通过这种方式,可以复用代码逻辑,并在需要时轻松调用通用函数来检查不同文本框的输入有效性和长度限制。

在上面提供的通用函数中,有三个参数,分别是:

    txtBox As Object:这是一个对象类型的参数,用于传递文本框控件对象。通过将文本框对象作为参数传递给函数,可以在函数内部对其属性进行操作,比如获取文本框的内容、设置焦点等。

    keyAscii As Integer:这是一个整数类型的参数,表示当前按下的键的 ASCII 值。在 KeyPress 事件中,可以通过这个参数获取用户按下的键的 ASCII 值,从而判断输入是否符合规定。

    maxLength As Integer:这是一个整数类型的参数,表示允许输入的最大字符长度。在函数中使用这个参数来检查文本框中输入字符的长度是否超过限制。

    通过将这三个参数传递给通用函数,可以使该函数具有通用性,可以用于检查不同文本框的输入有效性和长度限制,从而实现代码的复用。

第四次抽象

    上面代码除了限制长度,还限制了输入的内容只允许汉字、字母、数字、空格,但是向我上面说的,如过学号只限制数字,那这段代码就没法复用,两个办法
方法一:
把复用函数变成两个函数,一个用于限制输入的内容,另一个用于限制长度。

' 限制输入内容
Public Function CheckInputContent(txtBox As Object, keyAscii As Integer) As Boolean' 允许汉字、字母、数字、空格If Not ((keyAscii >= -20319 And keyAscii <= -3652) Or (keyAscii >= 48 And keyAscii <= 57) Or (keyAscii >= 65 And keyAscii <= 90) Or (keyAscii >= 97 And keyAscii <= 122) Or keyAscii = 32 Or keyAscii = 8) ThenkeyAscii = 0MsgBox "您输入的不是有效字符", 0, "温馨提示"CheckInputContent = FalseExit FunctionEnd IfCheckInputContent = True
End Function' 限制输入长度
Public Function CheckInputLength(txtBox As Object, maxLength As Integer) As Boolean' 判断字符长度If (Len(txtBox.Text) > maxLength) ThenMsgBox txtBox.Name & " 字符太长", 0, "温馨提示"txtBox.SetFocustxtBox.Text = ""CheckInputLength = FalseExit FunctionEnd IfCheckInputLength = True
End Function

在调用这两个函数时,可以分别对应不同的需求进行调用。例如,在文本框的 KeyPress 事件中

Private Sub txtBox_KeyPress(KeyAscii As Integer)Dim isValidContent As BooleanisValidContent = CheckInputContent(txtBox, KeyAscii)Dim isValidLength As BooleanisValidLength = CheckInputLength(txtBox, 10)  ' 限制最大长度为 10If Not isValidContent Or Not isValidLength ThenKeyAscii = 0End If
End Sub

    通过这种方法,可以更灵活地控制输入内容和长度的限制,使代码更易于维护和扩展。

方法二:就想把这两个函数写在一起
通过传入额外参数来指定不同的限制条件

Public Function CheckInputValidity(txtBox As Object, keyAscii As Integer, maxLength As Integer, allowChars As String) As BooleanDim validChars As StringvalidChars = allowChars' 检查是否为允许的字符If InStr(validChars, Chr(keyAscii)) = 0 And keyAscii <> 8 ThenMsgBox "您输入的不是有效字符", 0, "温馨提示"CheckInputValidity = FalseExit FunctionEnd If' 检查字符长度If (Len(txtBox.Text) > maxLength) ThenMsgBox txtBox.Name & " 字符太长", 0, "温馨提示"txtBox.SetFocustxtBox.Text = ""CheckInputValidity = FalseExit FunctionEnd IfCheckInputValidity = True
End Function

    在这个更新后的函数中,增加了一个名为 allowChars 的额外参数,用于指定允许输入的字符。在调用函数时,可以根据需要传入不同的 allowChars 参数来限制不同文本框的输入内容。

    在每个文本框的 KeyPress 事件中调用函数时,只需要额外指定对应文本框允许的字符即可

Public Sub RestrictInput(txtBox As Object, keyAscii As Integer, maxLength As Integer, inputType As String)Select Case inputTypeCase "Letter"If Not ((keyAscii >= 65 And keyAscii <= 90) Or (keyAscii >= 97 And keyAscii <= 122) Or keyAscii = 32) ThenkeyAscii = 0MsgBox "您只能输入字母和空格", 0, "温馨提示"End IfCase "Number"If Not (keyAscii >= 48 And keyAscii <= 57) ThenkeyAscii = 0MsgBox "您只能输入数字", 0, "温馨提示"End IfCase "Chinese"If Not (keyAscii >= -20319 And keyAscii <= -3652) ThenkeyAscii = 0MsgBox "您只能输入汉字", 0, "温馨提示"End IfEnd SelectIf (Len(txtBox.Text) > maxLength) ThenMsgBox txtBox.Name & " 字符太长", 0, "温馨提示"txtBox.SetFocustxtBox.Text = ""End If
End Sub

    将两个函数整合在一起,并添加了额外参数 allowChars 来指定不同文本框允许输入的字符。这样可以更灵活地控制每个文本框的输入内容和长度限制。

    在每个文本框的 KeyPress 事件中调用 CheckInputValidity 函数时,可以根据需要传入不同的 allowChars 参数来限制输入内容

Private Sub txtName_KeyPress(KeyAscii As Integer)RestrictInput txtName, KeyAscii, 10, "Letter"  ' 只允许输入字母和空格
End SubPrivate Sub txtNumber_KeyPress(KeyAscii As Integer)RestrictInput txtNumber, KeyAscii, 5, "Number"  ' 只允许输入数字
End SubPrivate Sub txtChinese_KeyPress(KeyAscii As Integer)RestrictInput txtChinese, KeyAscii, 10, "Chinese"  ' 只允许输入汉字
End Sub

简单工厂

    在VB6中,没有像接口和工厂模式这样的概念,可以使用类模块来实现类似的功能,但是这里我还是使用c#来写下实现的逻辑

定义接口: 首先,定义一个接口,其中包含用于校验文本框内容的方法。这个接口可以包含多个校验方法,具体根据需求而定。

public interface ITextBoxValidator
{bool IsValid(string text);
}

创建具体的校验器类: 实现接口,创建具体的文本框校验器类。每个类都实现了校验文本框内容的方法,根据不同的需求进行不同的校验逻辑。

public class AlphaSpaceValidator : ITextBoxValidator
{public bool IsValid(string text){// 实现只允许输入字母和空格的校验逻辑}
}public class NumericValidator : ITextBoxValidator
{public bool IsValid(string text){// 实现只允许输入数字的校验逻辑}
}

创建简单工厂类: 创建一个简单工厂类,根据输入的类型来实例化具体的校验器类。

public class TextBoxValidatorFactory
{public static ITextBoxValidator CreateValidator(string type){switch (type.ToLower()){case "alphaspace":return new AlphaSpaceValidator();case "numeric":return new NumericValidator();// 可以添加更多的具体实现类型default:throw new ArgumentException("Invalid validator type");}}
}

在使用时调用简单工厂创建校验器: 在需要使用文本框校验器的地方,调用简单工厂的方法根据需求创建具体的校验器实例。

string validatorType = "alphaspace"; // 或者 "numeric" 等
ITextBoxValidator validator = TextBoxValidatorFactory.CreateValidator(validatorType);// 在文本框输入事件中调用校验器的校验方法
textBox.TextChanged += (sender, e) =>
{if (!validator.IsValid(textBox.Text)){MessageBox.Show("Invalid input!");textBox.Text = ""; // 清空文本框内容或者采取其他处理方式}
};

    通过简单工厂,可以根据不同的需求创建不同的文本框校验器,实现对文本框内容的灵活校验。

反射

    最后,再说一下如果想要更灵活可以使用反射,那么实现的逻辑如下

1、定义接口和具体校验器类: 定义接口 ITextBoxValidator 和多个具体的校验器类,每个校验器类实现了接口中的校验方法。

2、创建简单工厂类: 创建一个简单工厂类 TextBoxValidatorFactory,其中包含一个静态方法 CreateValidator。在该方法中,使用反射来动态实例化校验器类。

3、使用反射实例化校验器类: 在 CreateValidator 方法中,根据传入的类型名称,使用反射获取对应类型的 Type 对象,然后使用 Activator.CreateInstance 方法实例化该类型的对象,并将其转换为 ITextBoxValidator 接口类型。

4、返回校验器对象: 将实例化的校验器对象返回给调用方,使调用方可以使用校验器对象进行文本框内容的校验。

通过使用反射,可以使简单工厂更加灵活,不需要在工厂类中硬编码每个具体的校验器类,而是根据传入的类型名称动态实例化相应的校验器类。这样,在需要添加新的校验器类时,只需创建新的类并实现接口,而不需要修改工厂类的代码。

    C#中具体实现反射的逻辑基本如下所示

1、获取程序集: 首先,需要获取包含要使用的类型的程序集。可以使用 Assembly.Load 方法加载程序集,或者使用已知的程序集,比如当前程序集。

2、获取类型: 一旦有了程序集,就可以从中获取所需类型。可以使用 Assembly.GetTypes 方法获取程序集中的所有类型,然后根据类型名称筛选出所需的类型。或者,如果已知类型所在的命名空间和程序集,可以直接使用 Assembly.GetType 方法获取指定类型的 Type 对象。

3、实例化对象: 一旦获取了类型的 Type 对象,就可以使用 Activator.CreateInstance 方法实例化该类型的对象。可以通过调用 CreateInstance 方法并传递类型的 Type 对象,来创建类型的实例。

public class TextBoxValidatorFactory
{public static ITextBoxValidator CreateValidator(string typeName){// 获取当前程序集Assembly assembly = Assembly.GetExecutingAssembly();// 获取指定类型的 Type 对象Type validatorType = assembly.GetType(typeName);if (validatorType == null || !typeof(ITextBoxValidator).IsAssignableFrom(validatorType)){throw new ArgumentException("Invalid validator type");}// 使用 Activator.CreateInstance 实例化对象并转换为 ITextBoxValidator 接口类型return (ITextBoxValidator)Activator.CreateInstance(validatorType);}
}

    在这段代码中,首先使用 Assembly.GetExecutingAssembly() 获取当前程序集。然后使用 assembly.GetType(typeName) 根据类型名称获取对应的 Type 对象。接着,通过检查获取的类型是否为 ITextBoxValidator 接口的实现,来确保类型的正确性。最后,使用 Activator.CreateInstance 实例化类型的对象,并将其转换为 ITextBoxValidator 接口类型,然后返回给调用方。通过反射来动态实例化任意类型的对象,从而实现灵活的对象创建。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/4918.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于SpringBoot+Vue高校宣讲会管理系统设计与实现

项目介绍&#xff1a; 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装高校宣讲会管理系统软件来发挥其高效地信息…

2024五一劳动节活动策划方案

2024五一劳动节朋克国风养生局&#xff08;回春集主题&#xff09;活动策划方案-48P 方案页码&#xff1a;48页 文件格式&#xff1a;pptx 方案简介&#xff1a; 大健康线下活动屡屡出圈 近年来&#xff0c;随着健康意识和生活水平的提升 人们对于自身健康越发关注&#…

面试题:分布式消息中间件 MQ

MQ官网文档&#xff1a; RabbitMQ&#xff1a;https://www.rabbitmq.com/docs RocketMQ&#xff1a;https://rocketmq.apache.org/zh/docs/ Kafka&#xff1a;https://kafka.apache.org/documentation/ DDMQ&#xff1a;https://base.xiaojukeji.com/docs/ddmq 面试题&#xff…

【4103】基于小程序实现的老年人健康管理平台

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;spring…

CIA组织MikroTik软路由攻击场景复现及后门加解密剖析

概述 写文章还是有一段时间了&#xff0c;发布的文章也是获得了不少小伙伴的关注&#xff0c;同时也和圈子里面的小伙伴慢慢的建立起了联系&#xff0c;平时也会时不时的一起探讨一些技术问题。因此&#xff0c;在最近和小伙伴的交流学习过程中&#xff0c;有一个小伙伴提到了…

Java:SpringBoot如何优化启动速度

一、yml中设置懒加载 spring:main:lazy-initialization: true 二、SpringBoot启动类中添加注解 Indexed &#xff08;Spring5才有该注解&#xff09; Indexed EnableAsync RestController SpringBootApplication(exclude {WxMaAutoConfiguration.class}) EnableTransactionM…

面试:MYSQL(SQL优化、MYSQL事务)

目录 一、SQL优化 1、如何定位慢查询 &#xff08;1&#xff09;方案一&#xff1a;开源工具 &#xff08;2&#xff09;方案二&#xff1a;慢日志查询 2、定位到慢查询时&#xff0c;如何优化 3、什么是索引 &#xff08;1&#xff09;底层结构 4、聚簇索引&#xff0…

优秀博士学位论文分享:动态三维场景理解与重建

优秀博士学位论文代表了各学科领域博士研究生研究成果的最高水平&#xff0c;本公众号近期将推出“优秀博士学位论文分享”系列文章&#xff0c;对人工智能领域2023年优秀博士学位论文进行介绍和分享&#xff0c;方便广大读者了解人工智能领域最前沿的研究进展。 “博士学位论…

【数据结构初阶】时间复杂度和空间复杂度详解

今天我们来详细讲讲时间复杂度和空间复杂度&#xff0c;途中如果有不懂的地方可翻阅我之前文章。 个人主页&#xff1a;小八哥向前冲~-CSDN博客 数据结构专栏&#xff1a;数据结构【c语言版】_小八哥向前冲~的博客-CSDN博客 c语言专栏&#xff1a;c语言_小八哥向前冲~的博客-CS…

matlab新手快速上手6(引力搜索算法)

本文根据一个较为简单的matlab引力搜索算法框架详细分析蚁群算法的实现过程&#xff0c;对matlab新手友好&#xff0c;源码在文末给出。 引力搜索算法简介&#xff1a; 引力搜索算法是一种启发式优化算法&#xff0c;最初于2009年由伊朗的Esmat Rashedi、Hossein Nezamabadi-p…

uniapp 对接facebook第三方登录

1.登录facebook开发者中心&#xff0c;打开我的应用页面在这里插入图片描述 2.创建应用 3.选择类型 4.填写信息 5.添加登录 6.添加平台 安卓密钥生成【需要 Java 环境!!! 和 openssl库】 Google Code Archive 的 Windows 版 openssl-for-windows OpenSSL 库 将openssl下载到…

如何利用FMEA进行不良事件分析——FMEA软件

免费试用FMEA软件-免费版-SunFMEA FMEA&#xff08;Failure Modes and Effects Analysis&#xff09;是一种预防性的质量工具&#xff0c;它帮助识别产品或过程中可能的故障模式&#xff0c;评估其对系统的影响&#xff0c;并优先处理那些对系统性能影响最大的故障模式。在医疗…

新时代教师口才演讲稿(3篇)

新时代教师口才演讲稿&#xff08;3篇&#xff09; 新时代教师口才演讲稿&#xff08;一&#xff09; 尊敬的各位领导、亲爱的同事们&#xff1a; 大家好&#xff01; 今天&#xff0c;我站在这里&#xff0c;深感荣幸与激动。在这个新时代里&#xff0c;教师的口才不仅仅是传…

webpack3升级webpack4遇到的各种问题汇总

webpack3升级webpack4遇到的各种问题汇总 问题1 var outputNamecompilation.mainTemplate.applyPluginWaterfull(asset-path,outputOptions.filename,{......)TypeError: compilation.mainTemplate.applyPluginsWaterfall is not a function解决方法 html-webpack-plugin 版…

上市公司-双重差分模型手动匹配绿色企业数据及参考资料

01、数据简介 双重差分模型&#xff08;DID&#xff0c;Differences-in-Differences&#xff09;是一种用于估计某个政策或处理效果的经济计量学模型。通过双重差分模型&#xff0c;可以控制一些不易观察的个体特征和时间趋势&#xff0c;以更准确地估计政策的效应。将绿色企业…

文件上传漏洞(upload-labs)

目录 一、文件上传漏洞 1.什么是文件上传漏洞 常见的WebShell 2.文件上传产生漏洞的原因 二、文件上传绕过 &#xff08;一&#xff09;客服端绕过-JS验证 1.前端验证 upload-labs第一关 &#xff08;二&#xff09;绕过黑名单验证 黑名单验证 1.特殊解析后缀 upl…

快速掌握Yarn:软件包管理工具的安装与使用指南【写作AI免费】

首先&#xff0c;这篇文章是基于笔尖AI写作进行文章创作的&#xff0c;喜欢的宝子&#xff0c;也可以去体验下&#xff0c;解放双手&#xff0c;上班直接摸鱼~ 按照惯例&#xff0c;先介绍下这款笔尖AI写作&#xff0c;宝子也可以直接下滑跳过看正文~ 笔尖Ai写作&#xff1a;…

Linux第十五章

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C&#xff0c;linux &#x1f525;座右铭&#xff1a;“不要等到什么都没有了…

MySQL随便聊----之MySQL的调控按钮-启动选项和系统变量

-------MySQL是怎么运行的 基本介绍 如果你用过手机&#xff0c;你的手机上一定有一个设置的功能&#xff0c;你可以选择设置手机的来电铃声、设置音量大小、设置解锁密码等等。假如没有这些设置功能&#xff0c;我们的生活将置于尴尬的境地&#xff0c;比如在图书馆里无法把手…

Hive安装部署

Apache Hive是一个基于Hadoop分布式文件系统、使用MapReduce算法执行大规模离线数据分析的数据仓库&#xff0c;本文主要描述Hive的安装部署。 如上所示&#xff0c;Hive总体应用架构图&#xff0c;其中&#xff0c;Hive基于HBase或者使用Hadoop分布式文件系统执行MapReduce的分…