.net 软件开发模式——三层架构
三层架构是一种常用的软件开发架构模式,它将应用程序分为三个层次:表示层、业务逻辑层和数据访问层。每一层都有明确的职责和功能,分别负责用户交互、业务处理和数据存储等任务。这种架构模式的优点包括易于维护和扩展、更好的组织结构和代码重用性、更高的安全性等方面。在具体实现中,需要根据不同的应用程序需求和技术平台选择适当的工具和框架,以达到最佳的开发效果和应用程序质量。
在 .NET 中,我们同样可以使用三层架构来构建我们的应用程序,实现表示层、业务逻辑层和数据访问层的分离。下面分别介绍在 .NET 中如何实现这三层架构。
1.表示层
在 .NET 中,我们可以使用 WinForms、WPF、ASP.NET 等技术来实现表示层的功能。在 WinForms 和 WPF 中,我们可以使用各种控件来构建用户界面,以显示和收集数据。在 ASP.NET 中,我们可以使用 ASP.NET Web 窗体、MVC、Web API 等技术来生成和管理 Web 页面。
在所有情况下,表示层的主要职责是接收用户输入和显示数据。例如,在 WinForms 中,我们可以使用窗体和控件来表示 UI,并通过事件处理程序和数据绑定来响应用户输入和显示数据。在 ASP.NET 中,我们可以使用代码片段来生成 HTML、CSS 和 JavaScript,并使用服务器端脚本和控件来处理事件和数据绑定。
2.业务逻辑层
在 .NET 中,我们可以使用类和接口来实现业务逻辑层。这些类和接口通常包括与应用程序相关的业务逻辑和规则,例如验证、授权、计算和处理数据。
业务逻辑层通常向表示层公开 API,以便 UI 可以与业务逻辑进行交互。例如,在 ASP.NET MVC 中,我们可以使用控制器和模型来处理请求,并使用视图来处理 UI。在 WinForms 中,我们通常将业务逻辑封装在一个专用的类或类库中,并使用事件处理程序和数据绑定来处理 UI。
3.数据访问层
在 .NET 中,我们可以使用 ADO.NET 和 Entity Framework 来访问数据。ADO.NET 提供了一组用于连接到和操作关系型数据库的类和接口,而 Entity Framework 则提供了一种对象关系映射(ORM)框架,使我们可以将对象与数据库记录进行映射和交互。
数据访问层通常会使用一些技术和工具来管理和维护数据,例如 SQL Server Management Studio 或 LINQ。我们可以使用 ADO.NET 和 Entity Framework 来执行数据库操作,并使用仓储模式或 DAL 等设计模式来创建底层数据库连接和访问代码。
下面通过一个简易的例题来演示三层架构的简易模式:
- 首先建立一个数据库(EmployeeSystem)
- 内部包含两个表(AdminInfo),(EmployeeInfo)
- AdminInfo表(登录验证表)包含两字段:主键:Account(varchar)用户名,Pwd(varchar) 密码 用于登录验证
- EmployeeInfo表(学生信息表)包含六个字段 :主键自增列:Id(int)编号,EmployeeName (varchar) 姓名,EmployeeNo(varchar)学号,EmployeeAge(int )年龄,EmployeeSalary(int)就业工资,EmployeeJob(varchar)职业名称
以上完成了示例数据库的搭建
接下来打开Microsoft Visual Studio2022,开始新建项目
- 在解决方案里创建一个Windows窗体应用程序取名UI作为我们这个项目的表示层
- 在解决方案里添加三个类库
- Model 模型层主要包含一些数据库中表对应的实体类,作为数据传递的载体
- DAL 数据访问层 :与数据库进行交互 执行增删改查的操作
- BLL 业务逻辑层:对业务逻辑进行处理 ,比如进行判断(必要的非空判断,添加前是否已经存在同样的数据)
6.打开UI找到引用:
第2步:定义连接字符串
name 属性是用于标识连接字符串的名称的字符串。
connectionString 是数据库连接时用到的字符串。
providerName 属性是用于指定数据提供程序的名称字符串。它通常与 connectionString 属性一起使用,来告诉应用程序要使用哪个特定的 ADO.NET 数据提供程序来访问数据库。
最后再到UI层
到这里了接下来进入Model层
我们首先从模型层开始写:
这里类里添加了两个类分别对应数据库里的两张表以及各字段
到这个模型层算搭建完(记得把修饰符改成公有的)
下一步给各层设置相互之间的引用
- UI表示层需要引用BLL业务逻辑层和Model模型层
- DAL数据访问层需要引入Model模型层
- BLL业务逻辑层需要引入DAL数据访问层和Model模型层
到这个项目的引用关系也就完事了
接下来就可以开始着手DAL数据访问层的内容了
DAL 层中的 SqlHelper 方法通常被称为数据访问助手方法(Data Access Helper Method),它们主要用于将应用程序的业务逻辑和底层数据访问逻辑分离开来。
通常情况下,SqlHelper 方法都包装了底层 ADO.NET API,以提供更简单、更易用的 API 接口,从而帮助开发人员更轻松地访问数据库。这些方法通常包括执行 SQL 语句、存储过程的方法,还有获取数据表、数据集等返回值的方法。
SqlHelper 方法可以接受连接字符串、SQL 语句、存储过程名称以及参数等信息作为参数,并使用它们来构建和执行数据库操作。通过将这些详细信息隐藏在方法内部,SqlHelper 方法帮助程序员简化了代码逻辑,提高了代码结构的清晰度和可读性。同时,SqlHelper 方法还可以处理数据库连接、异常处理等底层逻辑,从而提高了数据访问代码的可靠性和稳定性。
需要注意的是,不同的数据访问技术和开发框架通常有不同的 SqlHelper 实现方式,例如在 ASP.NET 中,我们通常使用 SqlHelper 类来访问 SQL Server 数据库,而在 Entity Framework 中,我们可以使用 DbContext 来管理数据访问逻辑,或者使用 LINQ 表达式来查询数据。
- 建立一个公有,静态类SqlHelper (内部方法也均为公有静态方法)
static readonly string ido= ConfigurationManager.ConnectionStrings["配置文件内add里的name名"].ToString();
//这段代码的作用是从应用程序配置文件 (App.config) 中获取名为 “配置文件内add里的name名” 的连接字符串,并将其存储在一个名为 “ido” 的静态只读字符串常量 ido 中。
2.接下来写下两个方法
思路:根据执行数据库增删改查操作的返回值来分类方法
1.查询操作返回的是DataTable 是一个 C# 中的数据表格类,它代表了一个内存中的数据表格,提供了一种方便的方法来存储和操作数据。
2.增删改操作的不同点只是sql语句有差异,他们共同点的返回类型都是受影响的行数。
3.由此存在了两种返回类型的值,可以在拟定两个返回值类型的方法分别为int和DataTable
3.查询表值的方法返回DAtaTable
public static DataTable selectall(string sql){//建立数据库连接 App.config里准备的数据库连接语句在这个时候可以体现用处了SqlConnection conn = new SqlConnection(ido);//打开数据库连接conn.Open();// 创建数据适配器对象SqlDataAdapter ter = new SqlDataAdapter(sql, conn);//实例化DataTableDataTable dt = new DataTable();// 使用数据适配器填充数据集ter.Fill(dt);//关闭数据库连接conn.Close();//返回值return dt;}
4.增删改的方法返回受影响行数
public static int CUD(string sql){SqlConnection conn = new SqlConnection(ido);conn.Open();//创建sql命令对象SqlCommand com= new SqlCommand(sql,conn);//用一个int 变量来接收受影响的返回行数int r=com.ExecuteNonQuery();//返回r的值return r;}
5.参数化命令的增删改方法
public static bool selectal(string sql,List<SqlParameter> list){SqlConnection conn = new SqlConnection(ido);conn.Open();SqlCommand com = new SqlCommand(sql, conn);//使用 AddRange 方法一次性添加多个 SqlParameter 对象,list需要转换成数组添加com.Parameters.AddRange(list.ToArray());//接收执行查询时返回的结果集中第一行第一列的值如果有数据就会大于0int r = Convert.ToInt32(com.ExecuteScalar());//判断r的值来决定返回的boolif(r >0) { return true; } else { return false; }}
到这一步数据访问助手的类已经完成了
DAL 数据访问层再为每张表定义一个类调用数据访问助手(在这里可以写入你需要执行的sql语句操作)
首先我们来做最简单的AdminInfo表(登录验证表)做执行一个登录的查询操作
这里需要主要预防sql注入攻击,所以要采用参数化命令的方法
在DAL层创建一个AdmDAL类调用SqlHelper类的方法
//参数为AdminInfo类public bool admopen(AdminInfo info){//sql语句string sql = "select count(*) from AdminInfo where Account=@Account and Pwd=@Pwd";//创建了一个 List<SqlParameter> 实例,用于存储多个 SqlParameter 对象。然后通过调用 List<T> 对象的 Add 方法向集合添加一个参数,或使用 AddRange 方法一次添加多个参数List<SqlParameter> list= new List<SqlParameter>();list.Add(new SqlParameter("@Account", info.Account));list.Add(new SqlParameter("@Pwd", info.Pwd));//返回值调用SqlHelper的方法(传入sql语句和参数化命令对象的值)最终返回一个bool类型的值return SqlHelper.selectal(sql, list);}
DAL层最后一个类EmpADL类 EmployeeInfo表(学生信息表)的各项操作
全部采取的sqlHelper的方法
简易的只需要写一条sql语句再返回调用方法(传入string sql语句参数)
有参数化命令的方法就根据sql语句创建一个list集合来存储方法类的值再返回参数化命令方法(sql语句,list集合)
//添加学生的方法public int EmpInsert(EmployeeInfo info){string sql = "insert into EmployeeInfo values(@EmployeeName,@EmployeeNo,@EmployeeAge,@EmployeeSalary,@EmployeeJob)";List<SqlParameter> list = new List<SqlParameter>();list.Add(new SqlParameter("@EmployeeName", info.EmployeeName));list.Add(new SqlParameter("@EmployeeNo", info.EmployeeNo));list.Add(new SqlParameter("@EmployeeAge", info.EmployeeAge));list.Add(new SqlParameter("@EmployeeSalary", info.EmployeeSalary));list.Add(new SqlParameter("@EmployeeJob", info.EmployeeJob));return SqlHelper.CUD(sql, list);}//修改方法public int EmpUpdate(EmployeeInfo info){string sql = "update EmployeeInfo set EmployeeName=@EmployeeName,EmployeeNo=@EmployeeNo,EmployeeAge=@EmployeeAge,EmployeeSalary=@EmployeeSalary,EmployeeJob=@EmployeeJob where Id=@Id";List<SqlParameter> list = new List<SqlParameter>();list.Add(new SqlParameter("@EmployeeName", info.EmployeeName));list.Add(new SqlParameter("@EmployeeNo", info.EmployeeNo));list.Add(new SqlParameter("@EmployeeAge", info.EmployeeAge));list.Add(new SqlParameter("@EmployeeSalary", info.EmployeeSalary));list.Add(new SqlParameter("@EmployeeJob", info.EmployeeJob));list.Add(new SqlParameter("@Id", info.Id));return SqlHelper.CUD(sql, list);}//删除方法public int EmpDelete(int id){string sql = $"delete from EmployeeInfo where Id={id}";return SqlHelper.CUD(sql);}//查询整表的方法public DataTable select(){string sql = "select * from EmployeeInfo";return SqlHelper.selectall(sql);}//根据编号查询的方法public DataTable selectID(int id) {string sql = $"select * from EmployeeInfo where Id={id}";return SqlHelper.selectall(sql);}//根据姓名模糊查询的方法public DataTable SelectName(string name) {string sql = $"select * from EmployeeInfo where EmployeeName like '%{name}%'";return SqlHelper.selectall(sql);}
以上这些就是DAL 数据访问层的基本方法 如果有额外的需求的话可以根据个人的要求结合所学的知识再去新建方法体
下面我们再来到BLL业务逻辑层
业务逻辑层需要做什么呢?
简单的来讲就是连接UI表示层和DAL数据访问层的桥梁,在这里会对数据进行一些加工例如判断数据是否为空等等,该怎么做需要屏幕前的你来发挥了
下面来看示例
public class EmpBLL{//实例化DAL数据访问层的EmpDAL类 并用方法调用EMpDAL类的方法private EmpDAL EmpDAL = new EmpDAL();//添加的方法public int EmpInsert(EmployeeInfo info){return EmpDAL.EmpInsert(info);}//修改的方法public int EmpUpdate(EmployeeInfo info){return EmpDAL.EmpUpdate(info);}//删除的方法public int EmpDelete(int id){return EmpDAL.EmpDelete(id);}//查询整表的方法public DataTable select(){return EmpDAL.select();}//根据姓名模糊查询的方法public DataTable SelectName(string name){return EmpDAL.SelectName(name);}//根据编号查询的方法public DataTable SelectID(int id){return EmpDAL.selectID(id);}
以上是EmployeeInfo学生信息表需要在表示层使用的方法
接下来是AdminInfo登录信息表需要的业务逻辑层方法
public class AdmBLL{//实例化数据访问层的AdmDAL类 并调用方法private AdmDAL AdmDAL=new AdmDAL();//登录方法public bool admopen(AdminInfo info){return AdmDAL.admopen(info);}}
到这里业务逻辑层也就完工了
最后一个UI 表示层 使用WinForms窗体应用程序搭建
首先完成一个简易的登录操作
在UI层建立一个窗体form1
使用控件 label* 2 ,textbox*2 button*1
给窗体登录按钮 双击添加点击事件
private void button1_Click(object sender, EventArgs e){//实例化模型层Model 的AdminInfo类 并把文本框的值赋给里面的字段AdminInfo info= new AdminInfo();info.Account = textBox1.Text;info.Pwd= textBox2.Text;//实例化BLL 业务逻辑层调用相对应的方法AdmBLL adm= new AdmBLL();//定义一个bool值的变量来接收返回值bool f= adm.admopen(info);//通过判断f的值来选择执行的操作,为true则弹窗登录成功并打开后续的窗体if (f==true){MessageBox.Show("登录成功");Form2 form2 = new Form2();form2.Show();}else { MessageBox.Show("登录失败"); }}
最后再给UI表示层添加一个form2窗体用于示例DAL和BLL的方法
为了简易采用dategridview
上面的窗体我们添加了多个按钮
先从窗体的加载事件开始,首先在窗体内部添加一个公有的BLL业务逻辑层的实例对象,便于调用其方法。
public EmpBLL empBLL = new EmpBLL();//实例化业务逻辑层
//初始化dategridview的表值
//将方法放入form2_load窗体加载事件中即可初始化值
public void select(){dataGridView1.DataSource = empBLL.select();//调用业务逻辑层查询整表的方法加载到datagridview控件中dataGridView1.ClearSelection();//取消默认选中状态}
删除按钮:button2
//删除按钮点击事件
private void button2_Click(object sender, EventArgs e){//对datagridview的选中项进行判断,未选中行时弹窗提示if (dataGridView1.SelectedRows.Count<=0){MessageBox.Show("请选中你需要删除的一行!");}else if (dataGridView1.SelectedRows.Count > 0){//获取选中行的第一行第一列的值用 一个int的变量来接收方便调用后续的业务逻辑层删除的方法int id = Convert.ToInt32(this.dataGridView1.SelectedRows[0].Cells[0].Value);//接收删除方法的返回值进行受影响的行判断int i = empBLL.EmpDelete(id);if (i > 0){//删除成功时弹窗提示并调用给datagridview赋值的方法(select())MessageBox.Show("删除成功");select();}else { MessageBox.Show("删除失败"); }}}
添加的按钮:button1
private void button1_Click(object sender, EventArgs e){//设置跳转到目标窗体并设置父子级Form3 form3 = new Form3();form3.Owner= this;form3.Show();}
form3窗体如下:
注:编号Id为自增列,所有只有五个字段
这里只需要为添加按钮添加点击事件:
//添加按钮点击事件
private void button1_Click(object sender, EventArgs e){//实例化EmployeeInfo类EmployeeInfo info = new EmployeeInfo();info.EmployeeName=textBox1.Text;info.EmployeeNo=textBox2.Text;info.EmployeeAge=int.Parse(textBox3.Text);info.EmployeeSalary=int.Parse(textBox4.Text);info.EmployeeJob=textBox5.Text;//给类中的每个字段赋值EmpBLL empBLL = new EmpBLL();//实例化BLL业务逻辑层的EmpBLL方法类,调用其中的添加方法把info作为参数传入int r= empBLL.EmpInsert(info);//用变量接收返回值来判断受影响行数if (r > 0) { MessageBox.Show("添加成功"); Form2 form=this.Owner as Form2;form.select();this.Close();} else { MessageBox.Show("添加失败"); }}
Form2 form=this.Owner as Form2:
这段的理解是:将当前窗体的拥有者窗体转换为 Form2 类型,并将转换后的实例赋值给了 form 变量。这样,我们就可以直接访问该窗体对象的属性和方法,例如 form 属性或者 Show 方法等。需要注意的是,如果 this.Owner 不是 Form2 类型的对象,则 form 变量将为 null。
之后再调用form2窗体的select()方法实现添加成功之后刷新form2的datagridview的集合
剩余的几个按钮就不一一进行讲解了,原理同上,有时间可以自己多练习熟能生巧,该文章只供参考用于理解软件开发模式的三层架构,相信认真看了的小伙伴能够看出对于传统的一个控件一个控件来完善的方式节省的代码量是非常可观的。
最后文章到这里就结束了,如果感觉对你有帮助的话可以点赞或收藏来加深理解。
再感谢认真看完文章的人对我的认可,本人会持续更新更多对粉丝有用的文章喜欢的可以关注支持哦
相关文章:
.net 软件开发模式——三层架构
三层架构是一种常用的软件开发架构模式,它将应用程序分为三个层次:表示层、业务逻辑层和数据访问层。每一层都有明确的职责和功能,分别负责用户交互、业务处理和数据存储等任务。这种架构模式的优点包括易于维护和扩展、更好的组织结构和代码…...
SpringBoot如何优雅的实现重试功能
文章目录 使用背景spring-retry介绍快速使用加入依赖开启Retry使用参数 使用背景 在有些特定场景,如和第三方对接。 我们调用接口时需要支持重试功能,第一次调用没成功,我们需要等待x秒后再次调用。 通常会设置重试次数,避免业务…...
【CEEMDAN-VMD-GRU】完备集合经验模态分解-变分模态分解-门控循环单元预测研究(Python代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
OpenText Exceed TurboX(ETX)—— 适用于 UNIX、Linux 和 Windows 的远程桌面解决方案
由于新技术的采用,以及商业全球化和全球协作的现实,几乎所有企业(无论其规模和所处行业)的员工的工作方式、时间和地点都发生了重大变化。业务领导者正在推动其 IT 部门提出解决方案,以帮助其远程员工提高工作效率&…...
【人工智能】— 逻辑回归分类、对数几率、决策边界、似然估计、梯度下降
【人工智能】— 逻辑回归分类、对数几率、决策边界、似然估计、梯度下降 逻辑回归分类Logistic Regression ClassificationLogistic Regression: Log OddsLogistic Regression: Decision BoundaryLikelihood under the Logistic ModelTraining the Logistic ModelGradient Desc…...
k8s pod “cpu和内存“ 资源限制
转载用于收藏学习:原文 文章目录 Pod资源限制requests:limits:docker run命令和 CPU 限制相关的所有选项如下: Pod资源限制 为了保证充分利用集群资源,且确保重要容器在运行周期内能够分配到足够的资源稳定运行&#x…...
datagrip 连接 phoenix
jar替换完后尽量重启datagrip. 然后重新连接即可. 不重启貌似报错... 效果:...
黑客入侵的常法
1.无论什么站,无论什么语言,我要渗透,第一件事就是扫目录,最好一下扫出个上传点,直接上传 shell ,诸位不要笑,有时候你花很久搞一个站,最后发现有个现成的上传点,而且很容…...
VB报警管理系统设计(源代码+系统)
可定时显示报警系统是一个能够定时并及时报警,提醒人们安全有效地按计划完成任务的系统。本论文从软件工程的角度,对可定时显示报警系统做了全面的需求分析,简要说明了该系统的构思、特点及开发环境;阐述了系统的主要功能,论述了它的设计与实现,并且叙述了系统的测试与评…...
Redis入门 - Redis Stream
原文首更地址,阅读效果更佳! Redis入门 - Redis Stream | CoderMast编程桅杆Redis入门 - Redis Stream Redis Stream 是 Redis 5.0 版本新增加的数据结构。 Redis Stream 主要用于消息队列(MQ,Message Queue)…...
微服务中常见问题
Spring Cloud 组件 Spring Cloud五大组件有哪些? Eureka:注册中心 Ribbon:负载均衡 Feign:远程调用 Hystrix:服务熔断 Zuul/Gateway:服务网关 随着SpringCloud Alibaba在国内兴起,我们项目中…...
更新删除清理购物车
目录 1 更新购物车 2 取会员门店购物车项 3 取会员门店购物车项(无缓存) 4 删除门店购物车某项 5 删除门店购物车多项 6 清理门店购物车 7 清理门店购物车 8 添加商品至购物车 9 添加商品至购物车...
基于Intel NUC平台的字符设备陀螺仪GX5-25驱动程序
陀螺仪GX5-25连接到Intel NUC上可能需要进行一些设备树的修改和编写驱动程序的工作。这是因为陀螺仪GX5-25可能需要特定的设备树配置和驱动程序来与Intel NUC的硬件和操作系统进行通信。 如果陀螺仪GX5-25没有官方的Linux驱动程序或文档,您可能需要自己编写驱动程序…...
建立小型医学数据库(总结)
建立小型医学数据库 小型医学数据库可以用于存储和管理医学数据,如患者病历、药品信息、试验结果等。这对于医疗机构和科研机构来说非常必要,可以提高数据管理和共享的效率,进而促进医学研究和诊疗水平的提升。 建立小型医学数据库有以下基本…...
Git学习笔记
文章目录 一. 引入1. SCM软件2. 概念 二. GitHubDesktop三. Git1. 版本号 (底层原理)1.1 视频笔记1.2 实操记录 2. Git命令2.0 汇总2.1 仓库操作2.2 文件操作2.3 分支操作2.4 标签操作2.5 远程仓库 四. idea操作 一. 引入 1. SCM软件 2. 概念 集中式版本控制 文件冲突 可以上…...
vue面试题1. 请说下封装 vue 组件的过程?2. Vue组件如何进行传值的?3. Vue 组件 data 为什么必须是函数?4. 讲一下组件的命名规范
1. 请说下封装 vue 组件的过程? 首先,组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,解决了我们传统项目开发:效率低、难维护、复用性等问题。 分析需求:确定业务需求,把页面中可以…...
Docker使用记录
文章目录 Docker基本使用Docker配置查看状态卸载安装使用 apt 存储库安装在 Ubuntu 上安装 Docker 桌面(非必要) Docker实例使用现有的镜像查找镜像拖取镜像列出镜像列表更新镜像导出镜像删除镜像导入镜像清理镜像查看容器导出容器导入容器-以镜像的方式创建容器重启容器进入容…...
OpenCV(图像处理)-基于Python-形态学处理-开运算、闭运算、顶帽、黑帽运算
1. 形态学2. 常用接口2.1 cvtColor()2.2 图像二值化threshod()自适应阈值二值化adaptiveThreshod() 2.3 腐蚀与膨胀erode()getStructuringElement()dilate() 2.4开、闭、梯度、顶帽、黑帽运算morphologyEx() 1. 形态学 OpenCV形态学是一种基于OpenCV库的数字图像处理技术&…...
chatgpt赋能python:Python支持跨平台软件开发
Python支持跨平台软件开发 作为一种高级编程语言,Python 以其丰富的库和跨平台支持而备受开发人员欢迎。Python 通过将应用程序的可移植性最大化,使得开发人员可以轻松地在不同的操作系统平台上构建和部署软件。 跨平台支持 Python 支持各种不同的操作…...
哈工大计算机网络课程网络层协议详解之:CIDR与路由聚集
哈工大计算机网络课程网络层协议详解之:CIDR与路由聚集 文章目录 哈工大计算机网络课程网络层协议详解之:CIDR与路由聚集CIDR与路由聚集CIDR路由聚集 CIDR与路由聚集 CIDR CIDR:无类域间路由(CIDR:Classless InterDo…...
C++ 教程(19)——日期 时间
C 日期 & 时间 C 标准库没有提供所谓的日期类型。C 继承了 C 语言用于日期和时间操作的结构和函数。为了使用日期和时间相关的函数和结构,需要在 C 程序中引用 <ctime> 头文件。 有四个与时间相关的类型:clock_t、time_t、size_t 和 tm。类型…...
React 应用 Effect Hook 函数式中操作生命周期
React Hook入门小案例 在函数式组件中使用state响应式数据给大家演示了最简单的 Hook操作 那么 我们继续 首先 Hook官方介绍 他没有破坏性是完全可选的 百分比兼容 也就说 我们一起的 类 class的方式也完全可以用 只要 react 16,8以上就可以使用 Hook本身不会影响你的react的理…...
C代码程序实现扫雷游戏纯代码版本
//test.c文件 #define _CRT_SECURE_NO_WARNINGS 1#include "game.h"void menu() {printf("***********************\n");printf("***** 1. play *****\n");printf("***** 0. exit *****\n");printf("*******************…...
ai代写---怎么在ubutnu服务器中安装mqtt
在Ubuntu服务器中安装MQTT Broker可以使用Mosquitto,它是一个开源的MQTT Broker实现,支持Linux、Windows和MacOS等多个平台。 以下是在Ubuntu服务器中安装Mosquitto的步骤: 更新apt-get包列表 打开终端,执行以下命令更新apt-get…...
【设计模式与范式:行为型】63 | 职责链模式(下):框架中常用的过滤器、拦截器是如何实现的?
上一节课,我们学习职责链模式的原理与实现,并且通过一个敏感词过滤框架的例子,展示了职责链模式的设计意图。本质上来说,它跟大部分设计模式一样,都是为了解耦代码,应对代码的复杂性,让代码满足…...
Kendo UI for jQuery---03.组件___网格---02.开始
网格入门 本指南演示了如何启动和运行 Kendo UI for jQuery Grid。 完成本指南后,您将能够实现以下最终结果: 1. 创建一个空的 div 元素 首先,在页面上创建一个空元素,该元素将用作 Grid 组件的主容器。 <div id"my-…...
初识Telegraf、InfluxDB和Grafana铁三角形成的监控可视化解决方案
文章目录 前言原始的监控靠人盯进化的监控靠批处理脚本高端的监控靠完整的可视化解决方案Telegraf、InfluxDB和Grafana铁三角TelegrafInfluxDBGrafana Grafana仪表板展示服务器资源总览负载和内存使用网络带宽磁盘IOIO延迟其他指标进程信息 总结 前言 数据监控目前用于各行各业…...
【哈佛积极心理学笔记】第20课 幸福与幽默
第20课 幸福与幽默 The vanguard of the positive psychology revolution: Our brain is basically a single processor, capable of consciouly choosing to devote resources either to the pain and suffering on one side, or viewing the world that lens of something l…...
设计模式-责任链模式
责任链模式 请求发送者和接收者连接成一条链,一个对象处理完,交给下一位,沿着链传递请求,这就是责任链模式。 角色 抽象处理者(Handler) 定义了处理请求的方法具体处理者(ContreteHandler&am…...
不变的是需求,变化的是解决方法和工具:探讨iPaaS与ESB的差异
在企业数字化转型过程中,企业需要面临日益复杂的业务和数据集成挑战。为了应对这些挑战,需要借助适当的解决方法和工具来实现系统间的通信和数据传输。在这方面,iPaaS(Integration Platform as a Service)和ESB&#x…...
企业网站建设预算方案/网站访问量
iOS8之后,苹果推出了WebKit这个框架,用来替换原有的UIWebView,新的控件优点多多,不一一叙述。由于一直在适配iOS7,就没有去替换,现在仍掉了iOS7,以为很简单的就替换过来了,然而在替换…...
江苏专业网站建设公司电话/跨境电商怎么做
目的: 代码的重构!我上一次写的随笔“C#学习——序列化和反序列化”对接口的理解似乎有误,接口基本上没进行什么设计,之后虽然也重新设计了一下, 但是写了两个接口IDeserialize和ISerialize每个接口里面只有一方法&…...
四川政府网站建设管理/电子技术培训机构
运行下面的命令可以检查rpm包安装后发生了什么改变# rpm -Va S.5....T. c /etc/watchdog.conf S.5....T. c /etc/xinetd.d/tftp S.5....T. c /etc/rc.d/rc.local S.5....T. c /etc/sysctl.conf S.5....T. c /etc/bashrc S.5....T. c /etc/dhcp/dhcpd.conf ....L.... c /…...
广州市官网网站建设平台/广告联盟app下载官网
# -*- coding: UTF-8 -*- import socket# 查看当前主机名 print(当前主机名称为 : socket.gethostname()) # 根据主机名称获取当前IP print(当前主机的IP为: socket.gethostbyname(socket.gethostname())) # 获取当前主机IPV4 和IPV6的所有IP地址 addrs socket.getaddrinf…...
山东seo推广多少钱/宁波厂家关键词优化
转自:http://bbs.21ic.com/icview-41930-1-1.html...
罗岗网站建设公司/网站收录服务
首先,要分别在两个文件中实现以下两个类 class Object { public: NewType ToType(); }; class NewType : public Object { } -------------------------------------------------------------------------------- 做法1 -------------------------------------------------…...