专题四:设计模式总览
前面三篇我们通过从一些零散的例子,和简单应用来模糊的感受了下设计模式在编程中的智慧,从现在开始正式进入设计模式介绍,本篇将从设计模式的7大原则、设计模式的三大类型、与23种设计模式的进行总结,和描述具体意义。
设计模式体系结构图
七大原则
开闭原则(OCP,Open Close Principle )
官方解释:对扩展开放软件实体应当对修改关闭(Software entities should be open for extension,but closed for modification)
白话解读:合成复用原则、里氏替换原则相辅相成,都是开闭原则的具体实现规范
就是有新的业务的时候,尽可能扩展展新类而不是修改旧类,实际开发的时候大家基本上都会这么做,这样对之前的业务影响比较小,所以很多原则设计模式就贯穿在日常开发中。
里氏替换原则(LSP,Liskov Substitution Principle)
👀官方解释:继承必须确保超类所拥有的性质在子类中仍然成立(Inheritance should ensure that anyproperty proved about supertypeobjects also holds for subtype objects)
是不是完全看不明白,俺也一样。
大白话:其实就是当我们需要开发功能的时候尽量通过继承父类,扩展父类功能的;而不是直接在原本的父类上修改。
依赖倒置原则(DIP,Dependence Inversion Principle)
官方定义:高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该以来抽象(High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions )
大白话:面向接口编程,而不是面向类编程:
例如:Controller里注入的是service接口而不是ServiceImpl,这样Controller就不用关心servcieImpl到底依赖的那些dao,同理可以推广的ServiceImpl依赖的是dao接口而不用关心具体实现。
单一原则(SRP,Single Responsibility Principle)
官方定义:一个类应该有且仅有一个引起他变化的原因,否则这个类应该被拆分(There should never be more than one reason for a class to change)
大白话:每个类只负责自己领域类的事情,而不是一篮子事情:当然要注意不是一个类只有一个方法。
例如:FileService可以处理文件上传下载方法,但是注册登陆等方法就不该放入该类中
接口隔离原则(ISP,Interface Segregation Principle)
官方定义:一个类对另一个类的依赖应该建立在最小的接口上(The dependency of one class to another on should depend on the smallest possible interface)
大白话:类应该建立自己专用的接口,而不是建立一个万能接口。
其实这个可以配合上面两个看,如果建立的万能接口,同时又要满足上面依赖倒置原则,那必定实现不了单一原则。
合成复用原则(CRP,Composite Reuse Principle)
由叫组合/聚合复用原则(Composition/Aggregate Reuse Principle,CARP)
软件复用时,要尽量先使用组合或者聚合等关联关系实现,其次才考虑使用继承关系实现。
大白话:优先是用组合而不是继承,这个是通用原则了,主要还是继承扩展起来没那么方便。
迪米特法则(LOD,Law of Demeter)
低耦合,高内聚。
最少知识原则(Least Knowledge Principle,.LKP)
只与你的直接朋友交谈,不跟“陌生人”说话 (TaIk only to your immediate friends and not to strangers)
其实就是引入一个中间者来进行交互Controller层不直接和Dao层直接交互
设计模式与组件生命周期关系图
以Java为例,通常我们会以结构型设计模式去构建类的类信息,通过创建型设计模式去创建对象,通过行为模式去控制对象的行为。
23种设计模式概述
前面三篇文章,基本上都多少涉及到了一点,这里咱们做个简单归纳的归纳总结,后面咱们咱们会一个一个的拆分。
结构型设计模式
外观模式(Facade)
为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
例子:在一个电商系统中,处理订单可能涉及多个子系统,如支付系统、库存系统、物流系统等。外观模式可以提供一个统一的接口来处理订单,从而简化客户端的调用。
适配器模式(Adapter)
将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
例子:MyBatis中的ResultSetHandler
将JDBC的结果集转换为自定义的对象类型。这个过程就是适配器模式的应用,将不兼容的接口进行适配。
桥接模式(Bridge)
将抽象部分与它的实现部分分离,使它们都可以独立地变化。
例子:Spring的JdbcTemplate和各种具体的数据库实现之间的分离。JdbcTemplate提供抽象操作,而具体的数据库操作由不同的DataSource实现,二者可以独立变化。
组合模式(Composite)
将对象组合成树形结构以表示“部分-整体”的层次结构。Composite模式使得用户对单个对象和组合对象的使用具有一致性。
例子:在一个文件系统中,文件和文件夹都可以视为节点。文件夹可以包含文件和其他文件夹,这形成了一个树形结构。组合模式使得文件和文件夹的操作一致。这个例子可能有过文件处理系统的小伙伴可能才好理解,再举一个列子:一个管理系统他的菜单树结构的,子与父结构相同这样是不是就好理解了一级菜单二级菜单嘛,无限套娃就行。
装饰模式(Decorator)
动态地给一个对象添加一些额外的职责。就扩展功能而言,Decorator模式比生成子类更为灵活。
例子:在一个图形编辑器中,可以对图形对象添加不同的装饰(如边框、阴影)。装饰模式可以动态地添加这些装饰,而不需要改变图形对象的类。
享元模式 (Flyweight)
运用共享技术有效地支持大量细粒度的对象。 例子:在一个文字处理系统中,每个字符都是一个对象。如果每个字符都单独存储,会占用大量内存。享元模式通过共享相同的字符对象,减少内存的使用。
代理模式(Proxy)
其他对象提供一种代理以控制对这个对象的访问。
例子:在一个远程服务调用系统中,客户端通过代理对象来访问远程服务。代理对象处理与远程服务的通信和数据传输,客户端只需调用代理对象的接口。SpringCloud种的Open Feign就是这个思想呢,当然代理我们一般分为静态代理和动态代理,但是现在很多时候静态代理和装饰器思想很接近,所以很多时候代理模式指的是动态代理,而java实现动态代理由离不开jdk或cglib,详细讨论的时候这一块将是重点。同样提到这里咱们就不得再提一下Spring种的Aop咯。
Spring的AOP也是代理模式的一个典型应用。通过创建代理对象,Spring AOP可以在方法调用前后添加额外的逻辑,如事务管理、权限检查等。
MyBatis也使用代理模式生成Mapper接口的实现类,调用实际的SQL操作。这个在框架中使用特别多,后面一定要好好说说。
创建型设计模式
创建模式主要的关注点是怎样将对象创建出来,将对象创建与使用进行剥离。像Spring框架就是依赖创建型设计模式,将我们开发者从对象的创建给剥离出来,对象的创建全部交给Spring托管,咱们安心写自己业务代码(方法的调用即可)。
单例模式(Singleton Pattern)
单例模式,在系统里,你要判断一下,如果有一些类,只需要一个实例对象就可以了,那就给那个类做成单例的模式(关键点就是构造方法私有化)Spring中的Bean对象默认都是单例的,后面在介绍具体的设计模式的时候在详细看代码。
简单工厂模式
工厂模式的核心思想,其实就是不要自己在代码里手动new一个实现类对象出来,因为那样的话,调用方就不是面向接口编程了,你还得自己去实现了。所以一般都是用工厂的思想来提供所有实现类实例,然后调用方面向接口来编程即可,接口不变,调用方代码不用变。
现在基本上很少去自己实现工厂模式了,因为有Spring框架,Spring的容器其实本质上就是个大工厂的概念,将你需要的对象都放到Spring容器里,需要的时候问Spirng取就完事。
工厂方法模式(Factory Method)
模板方法模式+简单工厂模式,简单工厂模式
抽象工厂模式(Abstract Factory)
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。在一个工厂中聚合多个同类产品的创建方法。简单理解为“工厂的工厂即可”。
建造者模式(Builder)
构造一个复杂的对象,很多的属性,有些属性构造的时候需要做一些校验,格式转换;
举个例子:当我们销售系统收到一笔订单的时候,在构建订单的时候需要对订单金额基础的校验、对产品的代码、产品类型做一些转换、供应商等。
原型模式(Prototype)
原型模式,以某一个对象为原型,然后对这个对象进行拷贝,得到拷贝后的另外一个对象
例子:很多BeanUtils之类的都有类似的功能,后面我们在分析具体的原理和对比他们的性能等。
行为型设计模式
责任链模式(Chain Of Responsibility)
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有对象处理它为止。
在Spring框架中,过滤器链的实现就体现了责任链模式的应用。每个过滤器负责处理请求的一部分逻辑,然后将请求传递给链中的下一个过滤器。这样就形成了一条过滤器链,所有的过滤器按顺序依次执行。
策略模式(Strategy)
可以将一系列算法,把它们一个个封装起来,并且使它们可以相互替换。本模式使得算法可独立于使用它的客户而变化。
例子:在一个支付系统中,支持多种支付方式(如支付宝、微信、信用卡、PayPal、比特币等)。每种支付方式是一个策略,用户可以在支付时选择不同的支付方式。
模版方法(Template Method)
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
例子:在一个文档处理系统中,可以有不同类型的文档(如Word文档、PDF文档等)的导出。导出的步骤大致相同:打开文档、读取内容、写入目标格式、关闭文档。具体的读取和写入步骤可以由子类实现。
命令模式(Command)
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
例子:在一个智能家居系统中,可以有各种命令(如小爱同学打开灯、关闭灯、调节温度等)。每个命令可以封装为一个对象,用户可以对命令进行操作,如执行、撤销等。
其实对于前后端分离项目,用户前端每次执行一个操作,对应后端的每个请求都可以看作是一个命令的执行,我们提供给前端的接口其实就是一个个封装的对象。
观察者模式(Observer)
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
例子:在一个股票交易系统中,投资者可以订阅股票价格的变化。当股票价格发生变化时,系统会通知所有订阅了该股票的投资者。
这个在Spring中的监听机制,其实就是可以看作是一个观察者模式,当模式泛化以后可以将消息中间件中的主题中的一组生产者一组消费者看作观察者模式。
访问者(Visitor)
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
例子:在一个编译器中,可以有不同的操作(如语法检查、代码优化、代码生成等)作用于语法树的各个节点。每个操作可以通过访问者模式实现。
状态模式(State)
允许对象在内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
例子:在一个订单处理系统中,订单可以有不同的状态(如新建、已支付、已发货、已完成等)。每种状态下订单的行为可能不同,比如在已支付状态下可以发货,但在新建状态下不可以。
这个状态模式和策略模式很想,不同的是状态模式有一个自动流转的状态机通过状态的不同来实现不同的算法。
解释器模式(Interpreter)
给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。
例子:在一个数学表达式计算器中,可以定义表达式的文法,并使用解释器模式来解析和计算表达式的值。
这玩意不知道咋解释,实际项目种使用的比较少,之前在科技部门做个一个通用的消息触达平台,定义了一些简单的占位符,通过占位符规则替换一些数据,应该类似解释器。
泛化到语言层面如Java 语言的Javac命令可以将Java源代码解析成Class文件,抑或现在比较火的Transformer框架中的编码器与解码器,将各种结构化数据解析成一组组向量后在来处理相似性问题,这个似乎更满足解释器模式的概念。这个模式先放一放,如果有小伙伴有比较深入的研究欢迎私信一起交流。
迭代器模式(Iteration)
提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
例子:在一个集合框架中,可以有各种集合(如数组、列表、集合等)。迭代器模式提供了一个统一的接口来遍历这些集合中的元素。
这种Java已经有很成熟的API了,咱们就不用自己去实现了,设计模式一定不能为了设计而设计,一定是为了解决实际问题。
中介者模式(Mediator)
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
例子:在一个聊天系统中,用户之间的消息传递通过一个中介者对象(如聊天服务器)进行,用户不需要直接知道其他用户的存在。
备忘录模式(Memento)
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后恢复对象到先前的状态。
例子:在一个文本编辑器中,可以有撤销和恢复功能。编辑器可以在执行某个操作前保存当前状态,以便用户需要时可以恢复到该状态。
其实Java中的序列化与反序列化可以看作是这个思想的扩展,需要保留的时候序列化的文件中,
设计模式带来的一些思考:
1、为什么学习设计模式
其实回答这个问题的时候,很多培训机构的老师或者网上资料都说设计模式是源码的基础,只有学会了设计模式才能看懂源码之类的观点。
这里的观点可能不太一样,设计模式也好抑或其他框架也罢,都是为了我们解决实际问题而设计出来的,有了设计模式的思想很多时候会给我们软件设计带来一些启发,这种场景是否可以有xxx模式的思想来解决呢?
其次任何一个成熟的项目都不可能由一个人来完成,设计模式思想的运用可以在团队合作的时候来规范团队。举个例子:在参与基金销售系统开发的时候,他的交易可以各种业务如:基金的认购、申购、赎回、修改分红方式等,每一种业务都有对应的处理逻辑,但是他们都需要和基金管理公司交互而和基金公司交互都是通过文件的形式。这样他们共同点可以抽象出来,那就是文件的处理可以放到模板方法统一实现,文件解析后的数据,再有个各子域去实现。这样子域可以由不同的人员来开发,代码风格更加统一好维护。
总结
在软件开发中,设计模式不仅仅是技术上的工具,更是一种思维方式和解决问题的哲学。它们通过丰富的实践和理论积累,帮助开发者在面对复杂需求和变化时保持清晰的思路和高效的开发策略。无论是单例模式的实例唯一性,还是策略模式的算法灵活性,设计模式都在实际项目中展现出其独特的价值。通过不断学习和应用设计模式,我们能够更好地理解和运用面向对象设计的原则和技巧,从而打造出更加健壮和可维护的软件系统。设计模式的智慧不仅体现在代码中,更融入到整个软件开发的文化与实践中,成为提升团队能力和项目质量的重要支柱,同样切记不能为了设计而设计,目前各种语言与框架已经很成熟,使用这些设计模式的时候一定要采取审慎原则。拿不定主意的时候多和公司资深前辈沟通。
相关文章:

专题四:设计模式总览
前面三篇我们通过从一些零散的例子,和简单应用来模糊的感受了下设计模式在编程中的智慧,从现在开始正式进入设计模式介绍,本篇将从设计模式的7大原则、设计模式的三大类型、与23种设计模式的进行总结,和描述具体意义。 设计模式体…...

基于X86+FPGA+AI数字化医疗设备:全自动尿沉渣检测仪
助力数字医疗发展,信迈可提供全自动尿沉渣检测仪专用计算机 随着信息技术的不断进步,医疗也进入了一个全新的数字化时代。首先是医疗设备的数字化,大大丰富了医疗信息的内涵和容量,具有广阔的市场发展前景。 数字化医疗设备&…...

vue2导入elementui组件库
第一步安装 npm i element-ui -S 第二步在main.js中导入 第三步使用然后在运行项目...

Django定时任务框架django-apscheduler的使用
1.安装库 pip install django-apscheduler 2.添加 install_app django_apscheduler 3.在app下添加一个task.py文件,用来实现具体的定时任务 task.pydef my_scheduled_job():print("这个任务每3秒执行一次", time.time()) 4.在app下创建一个manag…...

知识库文档处理,word转markdown
前一篇我讲解了如何对接MiniMax实现FAQ,其实知识库不仅仅可以实现FAQ,还能实现帮助文档的查询,内部培训资料的查询等等,但是这些培训资料大部分是word版本的,并且有层级结构,比如标题1,标题1-1等…...
TF和TF-IDF区别和联系
TF(Term Frequency)和TF-IDF(Term Frequency-Inverse Document Frequency)都是用于文本挖掘和信息检索的统计方法,用于评估一个词在文档或文档集合中的重要性。 一.TF(Term Frequency) 1.定义…...

02线性表 - 链表
这里是只讲干货不讲废话的炽念,这个系列的文章是为了我自己以后复习数据结构而写,所以可能会用一种我自己能够听懂的方式来描述,不会像书本上那么枯燥和无聊,且全系列的代码均是可运行的代码,关键地方会给出注释^_^ 全…...

高性能、安全、低碳绿色的趋势下,锐捷网络发布三擎云办公解决方案 3.0
桌面虚拟化作为云时代的主流和热门技术,已经取得了广泛应用。随着生成式 AI 爆炸式发展,CSDN 看到,人工智能正在引发计算、开发、交互三大范式的全面升级,技术开发或将迎来一次全新的科技变革周期,因此 VDI 云桌面随之…...
python3 shutil排除特定或者模糊匹配文件或目录
import shutil import fnmatchdef ignore_files(dir, files):# 定义要忽略的模式ignore_patterns = [file2.txt, dir2, *复制*.py]ignore_list = []<...

Spire.PDF for .NET【文档操作】演示:如何在 C# 中切换 PDF 层的可见性
我们已经演示了如何使用 Spire.PDF在 C# 中向 PDF 文件添加多个图层以及在 PDF 中删除图层。我们还可以在 Spire.PDF 的帮助下在创建新页面图层时切换 PDF 图层的可见性。在本节中,我们将演示如何在 C# 中切换新 PDF 文档中图层的可见性。 Spire.PDF for .NET 是一…...

新文件覆盖旧文件还能复原吗?八大excel文档修复软件免费
新文件覆盖旧文件还能复原吗?文件操作失误,尤其是新文件意外覆盖旧文件的情况时有发生,面对文件被覆盖的情况,我们不仅需要冷静应对,更需要掌握一系列有效的恢复策略。本文将深入探讨八种免费方法,旨在帮助…...

Android 10.0 Launcher3拖拽图标进入hotseat自适应布局功能实现一
1.前言 在10.0的系统rom定制化开发中,在对于launcher3的一些开发定制中,在对hotseat的一些开发中,需要实现动态hotseat居中 的功能,就是在拖拽图标进入和拖出hotseat,都可以保持hotseat居中的功能,接下来分…...

彻底解决idea的编解码问题
一、打开idea,找到Setting,点击File Encoding编解码设置,将以下标红的三个部分全部设置为UTF-8.同理如果你的项目使用的是GBK或者其他编码格式,那么也设置为统一。 二、点击Java Compiler设置补齐-encoding utf-8参数 三、如果你的项目使用到…...

仅两家!云原生向量数据库 PieCloudVector 全项通过信通院「可信数据库」评测
7月16日,2024 可信数据库发展大会在北京隆重举行。大会以“自主、创新、引领”为主题,近百位数据库领域的专家、学者齐聚一堂,带来高质量的数据库技术洞察与实战经验。 本次可信数据库发展大会中,中国信通院正式公布 2024 年上半年…...

vue使用x6画流程图,简单使用
官网 https://x6.antv.antgroup.com/tutorial/getting-started 安装 npm install antv/x6 --save 使用 <template><div>3333<div id"container" style"width: 800px;height: 800px;"></div></div> </template> <…...

低代码中间件学习体验分享:业务系统的创新引擎
前言 星云低代码平台介绍 星云低代码中间件主要面向企业IT部门、软件实施部门的低代码开发平台,无需学习开发语言/技术框架,可视化开发PC网页/PC项目/小程序/安卓/IOS原生移动应用,低门槛,高效率。针对企业研发部门人员少&#…...

阿里云ACP云计算高级攻城狮通用知识
🔥概述 阿里云云计算高级工程师ACP认证是面向使用阿里云云计算产品的架构、开发、运维类人员的专业技术认证,主要考核考生利用阿里云云计算技术服务体系设计稳定、安全、高性能、易扩展、低成本的企业云计算架构的能力。 前提:在写适用人群…...

log4js node日志插件
最近不是特别忙在用express搭建后台项目,在开发过程中遇到了需要输入日志的问 本来想直接用node自带的console来实现,后来发现console输出的日志达不到自己希望的 日志格式,后来各种百度发现了log4js插件,本文来记录log4js插件使用…...

【MQTT(3)】开发一个客户端,QT-Android安卓手机版本
手机版本更加方便 生成安卓库 参考了这个代码 在编译Mosquitto以支持安卓平台时,主要涉及到使用Android NDK(Native Development Kit)进行交叉编译。环境的准备参考之前的博客【QT开发(17)】2023-QT 5.14.2实现Andr…...

大数据之数据抽取架构演变过程
架构演变之Flink架构的演变过程 一、 起初搭建整个大数据平台是基于CDH这一套资源管理和整合的CM资源管理器搭建的 整个平台包括了: HDFS,YARN,HIVE,zoozie,FLINK,Spark,Zookeeper等组件搭建而成, 刚开始搭建的时候&am…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...