设计模式第七讲-外观模式、适配器模式、模板方法模式详解
一. 外观模式
1. 背景
在现实生活中,常常存在办事较复杂的例子,如办房产证或注册一家公司,有时要同多个部门联系,这时要是有一个综合部门能解决一切手续问题就好了。
软件设计也是这样,当一个系统的功能越来越强,子系统会越来越多,客户对系统的访问也变得越来越复杂。这时如果系统内部发生改变,客户端也要跟着改变,这违背了“开闭原则”,也违背了“迪米特法则”,所以有必要为多个子系统提供一个统一的接口,从而降低系统的耦合度,这就是外观模式的目标。
2. 定义和特点
(1). 定义
是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
(2). 优点
A. 降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类。
B. 对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。
C. 降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程,因为编译一个子系统不会影响其他的子系统,也不会影响外观对象。
(3). 缺点
A. 不能很好地限制客户使用子系统类。
B. 增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
3. 具体实现
(1). 模式结构
A. 外观角色:为多个子系统对外提供一个共同的接口。
B. 子系统角色:实现系统的部分功能,客户可以通过外观角色访问它。
C. 客户端:通过一个外观角色访问各个子系统的功能。
结构图如下:
(2). 使用场景
见下面代码。
(3). 代码实操
子系统代码
/// <summary>/// 子业务类1/// </summary>public class ChildService1{public void MyHandler1(){Console.WriteLine("我正在处理业务1");}}/// <summary>/// 子业务类2/// </summary>public class ChildService2{public void MyHandler2(){Console.WriteLine("我正在处理业务2");}}/// <summary>/// 子业务类3/// </summary>public class ChildService3{public void MyHandler3(){Console.WriteLine("我正在处理业务3");}}
外观角色
/// <summary>/// 外观角色/// </summary>public class FacadeService{private ChildService1 s1 = new ChildService1();private ChildService2 s2 = new ChildService2();private ChildService3 s3 = new ChildService3();public void MyHandler(){s1.MyHandler1();s2.MyHandler2();s3.MyHandler3();}}
测试
{Console.WriteLine("---------------下面是普通调用---------------");ChildService1 s1 = new ChildService1();ChildService2 s2 = new ChildService2();ChildService3 s3 = new ChildService3();s1.MyHandler1();s2.MyHandler2();s3.MyHandler3();Console.WriteLine("---------------下面是外观模式调用---------------");FacadeService f = new FacadeService();f.MyHandler();}
运行结果
4. 适用场景分析
(1). 对分层结构系统构建时,使用外观模式定义子系统中每层的入口点可以简化子系统之间的依赖关系。
(2). 当一个复杂系统的子系统很多时,外观模式可以为系统设计一个简单的接口供外界访问。
(3). 当客户端与多个子系统之间存在很大的联系时,引入外观模式可将它们分离,从而提高子系统的独立性和可移植性。
更多C++后台开发技术点知识内容包括C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,MongoDB,ZK,流媒体,音视频开发,Linux内核,TCP/IP,协程,DPDK多个高级知识点。
【文章福利】另外还整理一些C++后台开发架构师 相关学习资料,面试题,教学视频,以及学习路线图,免费分享有需要的可以点击 C++后端学习资料 免费领取
二. 适配器模式
1. 背景
在现实生活中,经常出现两个对象因接口不兼容而不能在一起工作的实例,这时需要第三者进行适配。例如,讲中文的人同讲英文的人对话时需要一个翻译,用直流电的笔记本电脑接交流电源时需要一个电源适配器,用计算机访问照相机的 SD 内存卡时需要一个读卡器等。
在软件设计中也可能出现:需要开发的具有某种业务功能的组件在现有的组件库中已经存在(且不能修改),但它们与当前系统的接口规范不兼容,如果重新开发这些组件成本又很高,这时用适配器模式能很好地解决这些问题。
2. 定义和特点
(1). 定义:
将一个类的方法转换成客户希望的另外一种要求的实现规范,使得原本由于接口不兼容而不能一起工作的那些类能一起工作,这就是适配器模式。适配器模式分为【类适配器模式】和【对象适配器模式】两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。
(2). 优点
A. 客户端通过适配器可以按照系统要求的编程规范透明地调用目标接口。
B. 复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类。
C. 将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题。
(3). 缺点
对类适配器来说,更换适配器的实现过程比较复杂。
3. 具体实现
(1). 模式结构
A. 目标接口:当前系统业务所要求遵守编程规范的接口,它可以是抽象类或接口。
B. 适配者类(被适配的类):第三方提供的新类或系统中已经存在的类,它与系统要求的编程规范的目标接口不兼容。
C. 适配器类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。
类适配器图:
对象适配器图:
(2). 使用场景
系统要求所有的数据库帮助类必须实现ISqlHelp接口,面向该接口编程,如SQLServerHelp类。 此时第三方提供了一个新的MySql的帮助类(假设是dll,不能修改),它的编程规范和ISqlHelp不兼容,这个时候就需要引入适配器类,使二者能相互兼容。
(3). 代码实操
系统要求的标准开发规范代码
/// <summary>/// 数据库连接抽象接口/// (代码中统一要求, 对数据库操作都要面向该接口编程)/// </summary>public interface ISqlHelp{public void Add();public void Del();public void Modify();}/// <summary>/// SQLServer数据库操作类/// (这是一个样例)/// </summary>public class SQLServerHelp : ISqlHelp{public void Add(){Console.WriteLine($"sqlserver数据库Add成功");}public void Del(){Console.WriteLine($"sqlserver数据库Del成功");}public void Modify(){Console.WriteLine($"sqlserver数据库Modify成功");}}
//1. 项目要求的标准编程模式Console.WriteLine("----------------------------1. 项目要求的标准编程模式---------------------------------");ISqlHelp s1 = new SQLServerHelp();s1.Add();s1.Del();s1.Modify();
第三提供的新类, 不满足开发规范
/// <summary>/// MySQL帮助类(第三方提供,不能修改)/// 没有实现ISqlHelp接口,有自己的一套逻辑./// 但是项目有统一编程要求,要基于ISqlHelp接口编程,/// 我们不能修改MySqlHelp内部的逻辑,所以这个时候要通过适配器模式进行适配/// </summary>public class MySQLHelp{public void AddMySQL(){Console.WriteLine($"MySQL数据库Add成功");}public void DelMySQL(){Console.WriteLine($"MySQL数据库Del成功");}public void ModifyMySQL(){Console.WriteLine($"MySQL数据库Modify成功");}}
//2. 第三方给的MySql帮助类,不符合标准模式Console.WriteLine("------------------2. 第三方给的MySql帮助类,不符合标准模式----------------------");MySQLHelp m = new MySQLHelp();m.AddMySQL();m.DelMySQL();m.ModifyMySQL();
通过适配器模式兼容新的开发规范
/// <summary>/// MySQLHelp适配器类1/// (通过继承的方式实现)/// </summary>public class MySQLHelpAdapter1 : MySQLHelp, ISqlHelp {public void Add(){AddMySQL();}public void Del(){DelMySQL();}public void Modify(){ModifyMySQL();}}/// <summary>/// MySQLHelp适配器类2/// (通过组合的方式实现,可以属性注入、构造函数注入、方法注入)/// </summary>public class MySQLHelpAdapter2 : ISqlHelp{public MySQLHelpAdapter2(){}//属性注入,直接写死private MySQLHelp _mySqlHelp = new MySQLHelp();/// <summary>/// 构造函数注入/// (可以改成抽象模式)/// </summary>/// <param name="mySqlHelp"></param>public MySQLHelpAdapter2(MySQLHelp mySqlHelp){this._mySqlHelp = mySqlHelp;}/// <summary>/// 方法注入/// (可以改成抽象模式)/// </summary>/// <param name="mySqlHelp"></param>public void SetAdapter(MySQLHelp mySqlHelp){this._mySqlHelp = mySqlHelp;}public void Add(){_mySqlHelp.AddMySQL();}public void Del(){_mySqlHelp.DelMySQL();}public void Modify(){_mySqlHelp.ModifyMySQL();}}
//3.通过适配器模式使用MySQL帮助类,且满足标准编程模式Console.WriteLine("------------------3.1 通过继承模式实现适配器------------------");ISqlHelp s2 = new MySQLHelpAdapter1();s2.Add();s2.Del();s2.Modify();Console.WriteLine("------------------3.2 通过组合模式实现适配器------------------");ISqlHelp s3 = new MySQLHelpAdapter2();s3.Add();s3.Del();s3.Modify();
适配器运行结果:
4. 适用场景分析
(1). 以前开发的系统存在满足新系统功能需求的类,但其接口同新系统的接口不一致。
(2). 使用第三方提供的组件,但组件接口定义和自己要求的接口定义不同。
三. 模板方法模式
1. 背景
在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关。
例如,去银行办理业务一般要经过以下4个流程:取号、排队、办理具体业务、对银行工作人员进行评分等,其中取号、排队和对银行工作人员进行评分的业务对每个客户是一样的,可以在父类中实现,但是办理具体业务却因人而异,它可能是存款、取款或者转账等,可以延迟到子类中实现。
这样的例子在生活中还有很多,例如,一个人每天会起床、吃饭、做事、睡觉等,其中“做事”的内容每天可能不同。我们把这些规定了流程或格式的实例定义成模板,允许使用者根据自己的需求去更新它,例如,简历模板、论文模板、Word 中模板文件等。
2. 定义和特点
(1). 定义
定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。它是一种类行为型模式。
(2). 优点
A. 它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。
B. 它在父类中提取了公共的部分代码,便于代码复用。
C. 部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。
(3). 缺点
A. 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
B. 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。
3. 具体实现
(1). 模式结构
A. 抽象类:负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。这些方法的定义如下。
① 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。
② 基本方法:是整个算法中的一个步骤,包含以下几种类型。
抽象方法:在抽象类中申明,由具体子类实现。
具体方法:在抽象类中已经实现,在具体子类中可以继承或重写它。
B. 具体子类:实现抽象类中所定义的抽象方法。
结构图如下:
(2). 使用场景
处理银行业务:取号→排队→办业务→评分, 除了办业务因人而异外(在子类中实现), 其它三步都是固定的,在抽象类中实现。
(3). 代码实操
抽象类:
/// <summary>/// 抽象类/// 处理银行业务:取号→排队→办业务→评分/// 除了办业务因人而异外, 其它三步都是固定的,在抽象类中实现/// </summary>public abstract class AbstractHandler{/// <summary>/// 模板方法/// 里面的步骤是按照固定顺序执行的/// </summary>public void TemplateMethod(){Handler1();Handler2();Handler3();Handler4();}/// <summary>/// 具体方法1/// </summary>public void Handler1(){Console.WriteLine("我是取号业务");}/// <summary>/// 具体方法2/// </summary>public void Handler2(){Console.WriteLine("我是排队业务");}/// <summary>/// 抽象方法3/// 个人业务,因人而异,需要去子类中实现/// </summary>public abstract void Handler3();/// <summary>/// 具体方法4/// </summary>public void Handler4(){Console.WriteLine("我是评分业务");}}
具体子类:
/// <summary>/// 具体子类1/// </summary>public class ChildHandler1 : AbstractHandler{/// <summary>/// 重写办个人业务的方法/// </summary>public override void Handler3(){Console.WriteLine("我来进行理财业务");}}/// <summary>/// 具体子类2/// </summary>public class ChildHandler2 : AbstractHandler{/// <summary>/// 重写办个人业务的方法/// </summary>public override void Handler3(){Console.WriteLine("我来进行存款业务");}}
测试:
{//流程1Console.WriteLine("---------------下面是流程1---------------------");AbstractHandler h1 = new ChildHandler1();h1.TemplateMethod();//流程2Console.WriteLine("---------------下面是流程2---------------------");AbstractHandler h2 = new ChildHandler2();h2.TemplateMethod();}
运行结果:
4. 适用场景分析
(1). 算法的整体步骤很固定,但其中个别部分易变时,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。
(2). 当多个子类存在公共的行为时,可以将其提取出来并集中到一个公共父类中以避免代码重复。首先,要识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
原文https://www.cnblogs.com/yaopengfei/p/13496730.html
相关文章:
设计模式第七讲-外观模式、适配器模式、模板方法模式详解
一. 外观模式 1. 背景 在现实生活中,常常存在办事较复杂的例子,如办房产证或注册一家公司,有时要同多个部门联系,这时要是有一个综合部门能解决一切手续问题就好了。 软件设计也是这样,当一个系统的功能越来越强&…...
flutter-第1章-配置环境
flutter-第1章-配置环境 本文针对Windows系统。 一、安装Android Studio 从Android Studio官网下载最新版本,一直默认安装就行。 安装完成要下载SDK,可能会需要科学上网。 打开AS,随便创建一个新项目。 点击右上角的SDK Manager 找到SDK…...
“消息驱动、事件驱动、流 ”的消息模型
文章目录背景消息驱动 Message-Driven事件驱动 Event-Driven流 Streaming事件规范标准简介: 本文旨在帮助大家对近期消息领域的高频词“消息驱动(Message-Driven),事件驱动(Event-Driven)和流(S…...
量化股票配对交易可以用Python语言实现吗?
量化股票配对交易可以用Python语言实现吗?Python 是一种流行的编程语言,可用于所有类型的领域,包括数据科学。有大量软件包可以帮助您实现目标,许多公司使用 Python 来开发与金融界相关的以数据为中心的应用程序和科学计算。 最重…...
机器学习洞察 | 一文带你“讲透” JAX
在上篇文章中,我们详细分享了 JAX 这一新兴的机器学习模型的发展和优势,本文我们将通过 Amazon SageMaker 示例展示如何部署并使用 JAX。JAX 的工作机制JAX 的完整工作机制可以用下面这幅图详细解释:图片来源:“Intro to JAX” video on YouT…...
OpenFaaS介绍
FaaS 云计算时代出现了大量XaaS形式的概念,从IaaS(Infrastructure as a Service)、PaaS(Platform as a Service)、SaaS(Software as a Service)到容器云引领的CaaS(Containers as a Service),再到火热的微服务架构,它们都在试着将各种软、硬…...
【算法设计与分析】STL容器、递归算法、分治法、蛮力法、回溯法、分支限界法、贪心法、动态规划;各类算法代码汇总
文章目录前言一、STL容器二、递归算法三、分治法四、蛮力法五、回溯法六、分支限界法七、贪心法八、动态规划前言 本篇共为8类算法(STL容器、递归算法、分治法、蛮力法、回溯法、分支限界法、贪心法、动态规划),则各取每类算法中的几例经典示例进行展示。 一、STL容…...
vue初识
第一次接触vue,前端的html,css,jquery,js学习也有段时间了,就照着B站的视频简单看了一些,了解了一些简单的用法,这边做一个记录。 官网 工具:使用VSCode以及Live Server插件(能够实时预览) 第…...
火山引擎入选《2022 爱分析 · DataOps 厂商全景报告》,旗下 DataLeap 产品能力获认可
更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 2 月 9 日,国内领先的数字化市场研究与咨询机构爱分析发布了《2022 爱分析DataOps 厂商全景报告》(以下简称报告),报…...
java-spring_bean的生命周期
生命周期:从创建到消亡的完整过程初始化容器 1. 创建对象(内存分配 ) 2. 执行构造方法 3. 执行属性注入(set操作) 4. 执行bean初始化方法 使用bean 执行业务操作 关闭/销毁容器 1.执行bean销毁方法 bean销毁时机 容…...
微服务相关概念
一、谈谈你对微服务的理解,微服务有哪些优缺点?微服务是由Martin Fowler大师提出的。微服务是一种架构风格,通过将大型的单体应用划分为比较小的服务单元,从而降低整个系统的复杂度。优点:1、服务部署更灵活࿱…...
论文解读:(TransA)TransA: An Adaptive Approach for Knowledge Graph Embedding
简介 先前的知识表示方法:TransE、TransH、TransR、TransD、TranSparse等。的损失函数仅单纯的考虑hrh rhr和ttt在某个语义空间的欧氏距离,认为只要欧式距离最小,就认为h和th和th和t的关系为r。显然这种度量指标过于简单,虽然先…...
js将数字转十进制+十六进制(联动el-ui下拉选择框)
十进制与十六进制的整数转化一、十进制转十六进制二、十六进制转十进制三、联动demo一、十进制转十六进制 正则表达式: /^([0-9]||([1-9][0-9]{0,}))$/解析:[0-9]代表个位数,([1-9][0-9]{0,})代表十位及以上 二、十六进制转十进制 正则表达…...
关于RedissonLock的一些所思
关于RedissonClient.getLock() 我们一般的使用Redisson的方式就是: RLock myLock redissonClient.getLock("my_order");//myLock.lock();//myLock.tryLock();就上面的例子里,如果某个线程已经拿到了my_order的锁,那别的线程调用m…...
C++:倒牛奶问题
文章目录题目一、输入二、输出三、思路代码题目 农业,尤其是生产牛奶,是一个竞争激烈的行业。Farmer John发现如果他不在牛奶生产工艺上有所创新,他的乳制品生意可能就会受到重创! 幸运的是,Farmer John想出了一个好主…...
MySQL8.x group_by报错的4种解决方法
在我们使用MySQL的时候总是会遇到各种各样的报错,让人头痛不已。其中有一种报错,sql_modeonly_full_group_by,十分常见,每次都是老长的一串出现,然后带走你所有的好心情,如:LIMIT 0, 1000 Error…...
具有非线性动态行为的多车辆列队行驶问题的基于强化学习的方法
论文地址: Reinforcement Learning Based Approach for Multi-Vehicle Platooning Problem with Nonlinear Dynamic Behavior 摘要 协同智能交通系统领域的最新研究方向之一是车辆编队。研究人员专注于通过传统控制策略以及最先进的深度强化学习 (RL) 方法解决自动…...
TrueNas篇-硬盘直通
硬盘直通 在做硬盘直通之前,在trueNas(或者其他虚拟机)内是检测不到安装的硬盘的。 在pve节点查看硬盘信息 打开pve的shell控制台 输入下面的命令查看硬盘信息: ls -l /dev/disk/by-id/该命令会显示出实际所有的硬盘设备信息,其中ata代…...
手机子品牌的“性能战事”:一场殊途同归的大混战
在智能手机行业进入存量市场后,竞争更加白热化。当各国产手机品牌集体冲高端,旗下子品牌们也正厮杀正酣,显现出刀光剑影。处理器、屏幕、内存、价格等各方面无不互相对标,激烈程度并不亚于高端之争。源于OPPO的中端手机品牌realme…...
dockerfile自定义镜像安装jdk8,nginx,后端jar包和前端静态文件,并启动容器访问
dockerfile自定义镜像安装jdk8,nginx,后端jar包和前端静态文件,并启动容器访问简介centos7系统里面我准备的服务如下:5gsignplay-web静态文件内容如下:nginx.conf配置文件内容如下:Dockerfile内容如下:run.sh启动脚本内容如下:制作镜像并启动访问简介 通过用docker…...
MongoDB 全文检索
MongoDB 全文检索 全文检索对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。 这个过程类似于通过字典中的检索字表查字的过…...
JS中声明变量,使用 var、let、const的区别
一、var 的使用 1.1、var 的作用域 1、var可以在全局范围声明或函数/局部范围内声明。当在最外层函数的外部声明var变量时,作用域是全局的。这意味着在最外层函数的外部用var声明的任何变量都可以在windows中使用。 2、当在函数中声明var时,作用域是局…...
汽车改装避坑指南:大尾翼
今天给大家讲一个改装的误区:大尾翼 很多车友看到一些汽车加了大尾翼,非常的好看,就想给自己的车也加装一个。 那你有没有想过,尾翼这东西你真的需要吗? 赛车为什么加尾翼?尾翼主要是给车尾部的一个压低提供…...
【Unity资源下载】POLYGON Dungeon Realms - Low Poly 3D Art by Synty
$149.99 Synty Studios 一个史诗般的低多边形资产包,包括人物、道具、武器和环境资产,用于创建一个以奇幻为主题的多边形风格游戏。 模块化的部分很容易在各种组合中拼凑起来。 包包含超过1,118个详细预制件。 主要特点 ◼ ◼ 完全模块化的地下城!包…...
知识汇总:Python办公自动化应该学习哪些内容
当前python自动化越来越受到欢迎,python一度成为了加班族的福音。还有大部分人想利用python自动化来简化工作,不知道从何处下手,所以,这里整理了一下python自动化过程中的各种办公场景以及需要用到的python知识点。 Excel办公自动…...
软件架构知识5-架构设计流程
一、识别复杂度 举例:设计一个亿级用户平台设计,直接对标腾讯的 QQ,按照腾讯 QQ的用户量级和功能复杂度进行设计,高性能、高可用、可扩展、安全等技术一应俱全,一开始就设计出了 40 多个子系统,然后投入大…...
【银河麒麟V10操作系统】修改屏幕分辨率的方法
文章目录前言系统概述方法1:使用命令行修改方法2:写文件修改方法3:界面端修改的方法前言 本文记录了银河麒麟V10系统修改分辨率的方法。 使用命令行修改写文件修改界面端修改的方法 系统概述 方法1:使用命令行修改 打开终端&am…...
pdf生成为二维码
当今数字时代,人们越来越依赖在线工具来处理各种任务,比如合并、拆分和压缩PDF等。Mai File就是这样一个在线工具,它可以将PDF文件转换成在线链接,方便您和他人轻松地查看和共享文件。 Mai File的使用非常简单,您只需…...
Yaklang websocket劫持教程
背景 随着Web应用的发展与动态网页的普及,越来越多的场景需要数据动态刷新功能。在早期时,我们通常使用轮询的方式(即客户端每隔一段时间询问一次服务器)来实现,但是这种实现方式缺点很明显: 大量请求实际上是无效的,这导致了大量…...
基于AIOT技术的智慧校园空调集中管控系统设计与实现
毕业论文(设计)题 目 基于AIOT技术的智慧校园空调集中管控系统设计与实现指导老师 XXXX 专业班级 电子商务2XXXX 姓 名 XXXX 学 号 20XXXXXXXXX 20XX年XX月XX日摘要近年来,随着物联网技术和人工智能技术的快速发展,智慧校园逐渐…...
无锡2019网站建设报价清单/宁波网站推广大全
在网页内预览pdf:http://www.jb51.net/article/117166.htm转载于:https://www.cnblogs.com/taketo/p/8204609.html...
网站建设比较好的/卡点视频免费制作软件
目录 替换功能 String replace(char old,char new)String replace(String old,String new) 去除字符串两空格 String trim() 按字典顺序比较两个字符串 int compareTo(String str)int compareToIgnoreCase(String str) 点击下方链接学习更多的String类 API深入研究 字符…...
网站标题空格/百度小说搜索热度排行榜
1.VGG 2.ResNet 3.DenseNet 4.ResNeXt 相关代码参考:PyTorch实现ResNeXt 5.ResNeSt 在ResNeXt的分组结构基础上,继续对每组划分R个split,执行Split Attention操作,最后将各个分组concatenate一起,经变换后和原始输入…...
wordpress特色图片/重庆seo关键词优化服务
ELK集群搭建 环境介绍 主机名备注web运行apache web服务node1作为elk节点1,kibana将安装在此节点node2作为elk节点2 所有主机修改主机名,以node1 [rootlocalhost ~]# hostnamectl set-hostname node1所有主机添加主机名解析 [rootlocalhost ~]# vim …...
热水器网站建设 中企动力/郴州网站推广
因为在前两个月的工作中,使用PPT的次数较多,所以这里准备继续写一下这个PPT2010的文章,不过之前通过标签搜索,我发现了两篇不错的介绍在PPT中插入视频的文章,这里给大家推荐一下,同时我这篇文章主要写一下那…...
国内著名平面设计师的个人网站/seo薪资seo
前言我于2020年开始接触、使用Vercel(ZEIT)的,要是我能早点知道的话,我也不会煞费苦心去优化Github上的个人博客的加载速度问题,当然国内也有类似Github的代码托管网站,如Gitee(码云),Coding(被腾讯收购,还…...