当前位置: 首页 > news >正文

设计模式的概念

设计模式主要分为三类:创建类的设计模式、结构型设计模式、行为型设计模式。
创建类的设计模式:简单工厂,工厂模式,抽象工厂,建造者,单例,原型
结构型设计模式:代理模式、享元模式
行为型设计模式:观察者模式

一、简单工厂模式

简单工厂模式:由三个角色构成,工厂类,抽象产品类,继承自抽象产品类的产品类。工厂类根据传入的参数决定初始化哪个产品类实例。这个模式的理解关键在于抽象产品类,也就是该工厂生产的产品是有共同的父类或者接口。目前项目中很多实用简单工厂模式存在滥用的情况,初始化的实例没有共同的父类,只是把初始化的代码放到了一个专门的类里。在调用的时候还是需要关注工厂类生产的产品如何使用。而标准的工厂类,生产的产品是有共性的,按照规范使用即可。举个例子:标准工厂模式下,工厂只生产小米手机,苹果手机,华为手机,他们的抽象产品类就是他们都是手机。而滥用情况下,工厂类生产手机,耳机,扫地机器人,吸尘器,冰箱等。

  • 错误示例:
AbstractProductClass (type) {}
FactoryClass  (type) {productInstance = new AbstractProductClass {type}productInstance.type = typereturn productInstance
}
xmProductInstance = new FactoryClass(‘xiaomi’)
  • 正确示例:
AbstractProductClass () {}
XiaoMiProductClass implement AbstractProductClass  () {}
iPhoneProductClass implement AbstractProductClass  () {}FactoryClass  (type) {if (type == ‘xiaomi’) {return new XiaoMiProductClass()} else if (type == ‘iPhone’) {return new iPhoneProductClass()}.
}
xmProductInstance = new FactoryClass(‘xiaomi’)

关键点:
1.
在这里插入图片描述
产品实例的属性和方法一般是定义在抽象类里的,如果产品自有特性太多,就变成我上面说的滥用了。工厂生产的就不是手机了,生产的更笼统了,变成生产电子设备了
2.
在这里插入图片描述
产品一定是有个抽象父类或者更抽象的接口去继承和遵守,这样使用的时候才可以忽略实例细节,按照规范使用。
抽象产品类是固定的,不能根据参数变化
3.
在这里插入图片描述
产品一定要有共性才可以用简单工厂
实际工作中,还是很容易滥用的,把一堆没有共性类的初始化放到一个工厂类中,根据不同的参数初始化不同的类。看上去是简单工厂,实际不是。

  • 总结
  1. 滥用的情况下只是把对象的实例过程集中到了一块,和分散的初始化没啥大的区别。简单工厂下初始化出来的实例因为有相同的接口,使用的时候就更方便了,使用方式也是统一的,甚至这些实例都是可以互相替换的。
  2. 弊端:简单工厂模式是不符合设计原则中的开闭原则的。比如你想生产新的一种手机vivo,你需要改工厂类,新增一个else if。这是不符合开闭原则的

二、工厂模式

由4个角色构成,抽象工厂父类具体工厂子类抽象产品父类具体产品子类。接我上面的话,简单工厂是把所有的手机生产都放到了一个工厂,工厂模式是把每个手机都单独建立一个工厂。这样工厂就需要有一个抽象父类了,抽象父类提供了统一的生产手机的方法,子工厂只需要实现这个方法就能生产对应的手机。这个模式下如果新增一种手机产品vivo,需要继承抽象工厂建立自己的vivo工厂,继承手机抽象类生成vivo手机类,然后用vivo工厂去生产vivo手机。符合开闭原则,但是有个问题就是类可能会越变越多,增加一定的复杂度。

  • 当你的简单工厂经常需要新增实例初始化,这样就会经常要改工厂类,就可以考虑用工厂模式优化一下。
  • 映射到现实生活中,没有一家工厂是生产两种手机的,小米手机是小米生产的,苹果是苹果公司生产的,如果想生产vivo,创立一家新公司vivo生产vivo就行了。这个就是工厂模式。

三、抽象工厂模式

在抽象工厂模式下还是有四个角色,抽象工厂父类具体工厂子类抽象产品父类具体产品子类,这个和工厂模式一模一样。唯一不同的是,抽象工厂父类需要再定义一个创建耳机的方法,然后定义耳机父类,耳机子类,然后加到里面就行了。这个在sdk中一些创建数组,列表啥的用。

  • 这个其实很好理解,想一个场景,上面的工厂都只能生产手机,如果你想生产耳机怎么办呢?这就出现了产品族,一个工厂可能生产的是一个产品族而不是单一的产品。

四、建造者模式

建造者模式:有四个角色,产品类抽象建造者类具体建造者类指挥者类。该模式主要解决的问题是如何创建一个复杂的对象,对象的复杂性主要体现在两个方面:初始化参数多,参数之间有依赖关系或者有校验要求。在不使用设计模式的情况下我们初始化一个复杂对象,就直接通过往构造函数中传递一堆参数来完成。如果觉得参数太多,写起来太长,又可以给这些参数各自定义一个set方法,通过写一堆set方法挨个赋值。但是这样还有一些问题,比如如何保证必填参数被设置了,一堆set方法被暴露出去外部可以修改这个对象,而我希望这个对象一旦创建就不可变,这个时候就引入了建造者模式。这个模式下建造者类需要定义产品类的属性和方法,而指挥者类接受一个建造者对象(Builer),然后调用Builder中的方法生产这个产品。

  • 完整示例
public class Phone{private String cpu;private String screen;private String memory;private String mainboard;private Phone(AbstractBuilder builder){this.cpu = builer.cpu;this.screen = builer.screen;this.memory = builer.memory;this.mainboard = builer.mainboard;}
}public class AbstractBuilder{private String cpu;private String screen;private String memory;private String mainboard;public AbstractBuilder cpu{return this;}public AbstractBuilder screen{return this;}public AbstractBuilder memory{return this;}public AbstractBuilder mainboard{return this;}public Phone build(){return new Phone(this)}
}public class ConcreteXiaoMiBuilder extend AbstractBuilder{public ConcreteXiaoMiBuilder cpu{this.cpu = @"小米CPU";return this;}public ConcreteXiaoMiBuilder screen{this.screen = @"小米显示屏";return this;}public ConcreteXiaoMiBuilder memory{this.memory = @"小米内存条";return this;}public ConcreteXiaoMiBuilder mainboard{this.mainboard = @"小米主板";return this;}
}public class Director(AbstractBuilder builder){Phone phone = builder.cpu().screen().memory().mainboard().build();
}main(int argc, char * argv[]){ConcreteXiaoMiBuilder *builder = new ConcreteXiaoMiBuilder();Phone *xiaomiPhone = new Director(builder);
}
  • 简化示例
public class Phone{private String cpu;private String screen;private String memory;private String mainboard;private Phone(Builder builder){this.cpu = builer.cpu;this.screen = builer.screen;this.memory = builer.memory;this.mainboard = builer.mainboard;}
}public class Builder{private String cpu;private String screen;private String memory;private String mainboard;public Builder cpu(String val){this.cpu = val;return this;}public Builder screen(String val){this.screen = val;return this;}public Builder memory(String val){this.memory = val;return this;}public Builder mainboard(String val){this.mainboard = val;return this;}public Phone build(){return new Phone(this)}
}main(int argc, char * argv[]){Builder builder = new Builder();Phone xiaomiPhone = builder.cpu('小米CPU').screen('小米显示屏').memory('小米内存条').mainboard('小米主板').build();
}

完整示例 - 》简化示例:完整示例中这个是比较规范的写法,实际使用的时候可以简化,即简化示例。比如如果只有一个builder,可以省略抽象builder,或者把抽象builder和具体builder结合一下,通过传递参数的形式返回不同的builder。指挥官的角色可以省略,其实他就相当于调用者。

五、代理模式

代理模式:分为静态代理和动态代理,静态代理有两种实现方式(继承,组合)。组合方式是代理类持有被代理类,代理类处理完一些自己的逻辑之后,再去调用被代理类,代理类和被代理类有相同的接口,调用者像使用被代理对象一样使用代理对象。继承的方式主要用在一些比如三方库这种没法重新定义其接口的情况,这种情况下需要在继承类中重写父类方法的方式插入自己的逻辑。静态代理的缺点是每个被代理的类都需要创建一个代理类,如果这些代理类的逻辑类似,代码会重复,且类的数量增多。这就引入了动态代理,多个被代理类共享一个代理类,通过运行时的一些方法,在运行阶段用代理类去替换被代理类做一些逻辑处理。代理模式常用场景:远程代理(在本地封装远程对象,调用者像使用本地函数一样,调用远程对象,个人认为云函数就是基于代理模式实现的),网络日志,网络缓存(在发起网络请求前后都可以对网络数据做缓存处理,或者日志的上报)等。

六、桥接模式

桥接模式:这个模式比较难理解,用的也比较少,用来解决继承关系的指数爆炸。举例:形状(Shape)包含圆形,方形,椭圆形等,而颜色包含红色,绿色,蓝色等。如果我们用继承的关系去定义这些形状和颜色的组合,会有n*m个类。在桥接模式下Shape作为顶层的抽象类,可以扩展出多个抽象子类(圆形,方形等),同时Shape持有一个颜色的引用。这样当需要一个红色的圆时,只需要把红色对象传递到circle类中,就可以得到一个红色的圆。这个模式也遵循了组合原则,用组合的方式减少继承的层级。工作中当你意识到继承层次过深的时候,多考虑能不能用组合的方式处理,桥接只是处理这种问题的一个模式。另外在看别人的代码时,如果遇到了这种桥接模式,能看懂就行。

七、装饰者模式

装饰者模式:对一个对象能力的增强。装饰器类和源类具有相同的抽象类。装饰器类持有源类,因为装饰器和源类继承自相同的父类,所以装饰器和装饰器可以嵌套调用,实现对源类的多层次装饰。
主要由4个角色构成:component接口;concretecomponent实现类,继承自component;Decorator装饰器抽象类,继承自component,持有对实现了component接口的类的引用;ConcreteDecorator装饰器实现类。

八、适配器模式

适配器模式:这个模式是一种妥协的模式,为解决兼容性提出的模式。如果代码从一开始就设计的比较好,这个模式就不会用到。但实际情况下这个模式是很常见的。最常见的场景是原接口废弃,但是如果直接改原接口会导致代码调用的地方都要跟着变动,所以一般情况下都是重新定义新接口,然后老接口调用新接口,将老接口标记为deprecated。还有一种常见场景是在使用一些三方库的时候,由于同类型众多三方库中对外接口不一致,为了能在后期方便对三方库替换,可以考虑引入适配器,调用的时候通过适配器调用,如果后面需要替换三方库,只需要改动适配器的代码即可。

九、门面模式

门面模式:这个模式很简单,主要是针对接口的封装,方便子系统被高层系统调用。举例:后端基于接口的可复用性,定义了细粒度的接口a,b,c,d。前端在渲染页面数据时,需要用到a,b,d接口,那我们就需要发起3次请求,如果这三次请求还有顺序要求,那对前端来说使用成本就比较高,并且多个接口也影响网络性能。这个时候就可以要求后端基于a,b,c子接口,提供一个门面接口,将这三个接口包起来。门面就相当于对外的一个展示,隐藏了内部的细节。

十、组合模式

组合模式,这个模式比较少见,针对的是很特殊的数据结构用。如果你的数据结构是一种树状的,用组合模式处理起来就方便。常见的比如公司组织架构,文件夹目录。这种可以考虑用组合模式。

十一、享元模式

享元模式:这个模式理解和使用起来也很简单,就是为了节省内存对对象的共享使用。举例:在棋牌类游戏中,假设有1000个游戏虚拟房间,每个房间都有关于棋子的信息,这样棋子的信息也会创建1000个,但他们又很相似,这个时候就可以用享元模式,把棋子信息设计成共享的。这个和单例模式有一些相似,但是设计初衷不一样。单例是为了限制对象的个数,享元模式是为了节省内存。

十二、原型模式

就是对对象的copy,需要注意深浅copy。

十三、观察者模式

观察者模式:这个模式也是很常用的,理解也很简单,也叫发布订阅模式。iOS下系统框架实现了这种设计模式,可以直接用,但是不太好用,所以有时候会自己写一个。前端和安卓常见的实现方式叫eventbus,有阻塞和非阻塞两种方式,我们一般都是用的阻塞。

十四、模板方法模式

模板方法模式:这个模式也比较好理解,通过继承的方式抽象方法步骤,形成固定的调用模板,然后子类去重写被调用的这些步骤。这其中还有一个小点就是钩子,可以在这些步骤中间插入一些钩子,实现扩展能力。举例:有个抽象类方法A,其中定义了一个方法a,这个方法会依次调用a1,a2,a3,这样基于A的子类B,只需要重写a1,a2,a3,就可以实现固定的调用顺序。这个可能在实际工作中已经在用了,只不过不知道这就叫模板方法。

十五、责任链模式

责任链模式:用一个线性表按照顺序存储了若干处理对象,然后把被处理对象传递给管理这个线性表的对象(chain),chain按照顺序依次处理该对象。
有两种实现方式:链表,数组。有两种场景:遇到有对象能处理则停止;遇到有对象处理不停止,直到chain中所有对象都处理一遍。这个地方所有的处理对象也有一个共同的抽象父类,抽象父类主要定义了处理方法和调用下一个处理对象。
(chain数组中存了一堆类的实例对象,这些对象有共同的抽象类,在处理一个被处理对象B时,就从数组里取实例对象去处理B就完了,你可以选择遇到有能处理B的就break,也可以选择continue(这样就是另一个变种,数组中每个对象都会处理一下B)。)

十六、状态机模式

状态机:这个模式和前面说的组合模式(处理树形数据模型时:组织架构,文件结构)都不是常用的模式,但是在特定场景下又特别好用。我们项目中播放器状态管理就用的状态机。主要由3个部分组成,状态,事件,动作。当一个状态触发了某个事件后做对应的操作并且切换状态。有三种实现方式:分支逻辑(其实就是ifelse这种,在一些比较简单的状态机下用,这个并不推荐,扩展性差,更像是硬编码);查表法:这个模式适用于动作比较简单的情况,大概意思就是构建一个状态转移的二维表,一个动作二维表,这两个表甚至可以做成远程配置的,当事件触发的时候直接从这两个表查映射关系做对应操作。状态模式:把状态和动作封装成类,每个状态处理自己遇到这些事件的状态转移和动作处理。这种模式会产生很多类,但是能处理动作比较复杂的场景。

十七、迭代器模式

迭代器模式:有两个角色:容器,迭代器。而容器又分容器接口,容器实现,迭代器也分为迭代器接口,和迭代器实现。对于迭代器的接口,主要含有三个方法:hasNext,currentItem,next。容器为啥也需要有个接口呢,这个主要是因为接口可以统一迭代器的创建,比如容器接口定义一个iterator方法,用来创建一个迭代器实例,容器的接口实现类只需要实现这个方法,返回一个自己的迭代器实例即可。迭代器实例通过依赖注入的方式持有容器实例,然后迭代器通过操作这个容器实现对应的那三个方法。
(这个模式在实际的工作中使用时比较少的,因为大部分变成语言下都对自己容器实现了迭代器,只需要直接调用就行了,很少需要自己实现一个迭代器。并且对于像数组,链表这种简单的容器,甚至不需要用迭代器更容易访问。但是对于更复杂的容器,比如树,图他们有更复杂更多样的遍历路径,这种情况就可以实现多个迭代器,根据不同的需求,调用不同的迭代器。)

十八、访问者模式

访问者模式:大概得使用场景就是,当一个对象需要针对这个对象做很多操作的时候,这个类就会变得越来越复杂。访问者模式将对象模型和操作分离开来,访问者可以操作这个对象里的元素。比如,你有一个房子,房子里有各种电器设备和生活用品,在非访问者模式下,每个设备坏了,你就去学习一种维修能力,最后你能修这个房子里的所有电器,对应到编程里面,就是这个类变得非常大。而访问者模式下,电器和维修工是分开的,当你需要维修的时候,有个访问者来敲门,你开们让他进来维修,修完他就走了。在软件设计里就理解为,数据对象模型和操作分离开,防止数据对象里包含了太多业务操作逻辑。以上是一个大概的理解,因为这个比较少见,细节上没有细研究。以后遇到这种场景再看吧

十九、备忘录模式

备忘录模式:主要使用场景:需要回滚操作的场景或者需要恢复数据的场景。主要有三个角色:原始类,备忘录类,负责人类。原始类就是你要备份的对象,这个对象有一些类似set方法可以改变对象本身,所以这个对象不适合用来做备忘录,备忘录类是一个不可变对象,也就是没有set方法,只有get方法,用来保存原始类的状态。而原始类提供了创建备忘录类实例的方法,并且也提供了通过备忘录类,重新赋值原始类的方法。而负责人类就是对备忘录类实例的一个持有和操作,它提供一个容器持有了所有的备忘录类,通过备忘录类就可以用来恢复一个原始类,而通过原始类也可以创建一个备忘录类存储在负责人类中。
(这个模式实现方式是很多种的,核心就是你原来的对象因为一般都是可变的,直接缓存有很多问题,不满足封装原则。所以弄了一个备忘录类,这个类通过初始化方法之后,就不能被改变了,就像是给这个对象拍了一个快照一样。之后通过对快照的操作完成回滚,恢复等操作。)

二十、命令模式

命令模式:这个模式使用的也比较少,主要是后端用的比较多一点。在经典设计模式里,这个解释很复杂,看不懂。王争那个文中对这个做了进一步解释,就是把一个函数封装到对象里,这样每一个命令对应的处理函数就变成了一个对象,对象可以传来传去,还可以异步调用,撤销等操作。大概理解就行吧,实际没遇到过这种使用场景。遇到了再说

二十一、解释器模式

解释器模式:这个模式更少见,遇到能看懂就行,使用场景是对语法规则进行解析,比如编译器里的语法解析器,规则引擎,正则表达式解析。实现方式也比较灵活,没有固定范式。
把一个复杂语句的解析进行拆分,拆成更多个小的解析类,最后把各个解析类的结果合并起来,形成最终的解析结果。举一个简单例子:比如对一个算数表达式(包含数字,加减乘除)进行解析,可以生成5个解析类NumberExpression、AdditionExpression、SubstractionExpression、MultiplicationExpression、DivisionExpression,它们有一个共同的接口,有一个共同的方法interpret(),在遇到一个表达式的时候就分别用这几个类进行细分的解析。

二十二、中介者模式

中介者模式:这个模式也不常用,但是理解起来比较简单,使用场景是如果多个对象之间相互调用,会造成关系比较复杂,耦合性比较强。这个时候引入一个中介者,所有的对象都通过中介者进行交互。这样就把一个多对多的关系,变成了一对多。缺点是这样可能会导致中介者变得特别庞大。现实中例子,就是飞机和塔台的关系,飞机把自己的定位等信息告诉塔台,塔台进行航线的协调工作。编程中的例子是:一个对话框中有一堆UI组件,这些组件之间会相互影响,如果这些逻辑都写在一块,组件也会变得不可复用,交互也会乱。这个时候就可以引入一个中介者。

总结

以上是所有的设计模式,有些比较常用也好理解。有些不常用也不好理解。整体上对设计模式有个概念了,在日常编码过程中,需要注意的是,当遇到一些比较复杂的编码需求时,尤其是代码越写越乱的时候,多思考一些面向对象编程和设计模式,看看代码能不能优化,写出更容易维护,阅读,复用的代码。

相关文章:

设计模式的概念

设计模式主要分为三类:创建类的设计模式、结构型设计模式、行为型设计模式。 创建类的设计模式:简单工厂,工厂模式,抽象工厂,建造者,单例,原型 结构型设计模式:代理模式、享元模式 行…...

VMware17下载与安装

1.下载 通过百度网盘分享的文件:VMware17 链接:https://pan.baidu.com/s/1gCine3d3Rp_l3NYAu5-ojg 提取码:ek25 --来自百度网盘超级会员V3的分享 2.安装...

mv命令学习

移动和重命名文件 mv mv命令的作用就是将文件系统的文件从一个地方移动到另一个地方。 $ pwd /home/scott/libby $ ls libby_arrowrock.jpg libby_bak.jpg libby.jpg ➥libby_on_couch.jpg on_floor $ ls ~/pictures/dogs libby_on_floor_01.jpg libby_on_floor_03.jpg li…...

西北航天基地采用Infortrend NAS存储做影视后期及共享

用户背景: 创建最早的综合型航空航天基地,占地5万平方米,每年约300天进行航天试验 挑战: 西北航天基地规模大任务多,分别有不同的项目组负责试验,项目组需要获取试验任务影像资料,用于分析总…...

GitHub每日最火火火项目(8.6)

项目名称:bghira / SimpleTuner 项目介绍:SimpleTuner是一个通用的微调工具包,主要面向Stable Diffusion 2.1、Stable Diffusion 3、DeepFloyd和SDXL等模型。它旨在为这些模型提供一种方便的方式进行微调,以适应不同的应用场景和需…...

LangChain与CI/CD的无缝对接:自动化部署的新前沿

LangChain与CI/CD的无缝对接:自动化部署的新前沿 在当今快速发展的软件开发领域,持续集成/持续部署(CI/CD)已成为提升开发效率和软件质量的关键实践。LangChain,作为一个假设的编程辅助工具,如果存在&…...

Laravel为什么会成为最优雅的PHP框架?

目录 1. 设计哲学 1.1 表达性语法 1.2 约定优于配置 1.3 优雅的异常处理 2. 核心特性 2.1 Eloquent ORM 2.2 路由系统 2.3 Blade模板引擎 2.4 Artisan命令行工具 3. 社区支持 3.1 丰富的文档和教程 3.2 Packalyst:丰富的扩展包 3.3 社区活动和会议 4.…...

LabVIEW中的Reverse String函数与字节序转换

在LabVIEW中,数据的字节序(也称为端序)问题通常出现在数据传输和存储过程中。字节序可以分为大端(Big-Endian)和小端(Little-Endian),它们分别表示高字节存储在低地址和低字节存储在…...

用OpenCV与MFC写一个简单易用的图像处理程序

工厂里做SOP及测试报告以及员工资格鉴定等常需用到简单的图像处理,PS等软件正版费用不菲,学习起来成本也高。Windows自带的图像处理软件,用起来也不是那么得心应手。因此我用OpenCV与MFC写了一个简单易用的图像处理程序。 程序界面 基于简单…...

go语言的actor框架和air工具有什么区别?

Go语言的Actor框架和Air工具在多个方面存在显著的区别,主要体现在它们的设计目的、功能特性以及应用场景上。 ### Go语言的Actor框架 **设计目的与功能特性**: * **设计目的**:Actor框架是专为高并发和分布式系统设计的编程模型。它通过将系统…...

e6.利用 docker 快速部署自动化运维平台

利用 docker 快速部署自动化运维平台 1. 安装docker2. 拉取镜像3. 启动容器4. 初始化5. 访问测试 Spug 面向中小型企业设计的轻量级无 Agent 的自动化运维平台,整合了主机管理、主机批量执行、主 机在线终端、文件在线上传下载、应用发布部署、在线任务计划、配置中…...

回顾前面刷过的算法(4)

今天回顾一下下面三个算法,涉及到了动态规划、合并链表、位运算,好吧,让我们再次手敲一遍 //乘积最大子数组//思路: 维护三个变量,imax最大前缀乘积 imin最小前缀乘积 max最大连续乘积//由于元素有正负,imax和imin需…...

SourceTree配置多个不同Remote地址的仓库

需求 在我们开发过程中,有可能需要拉取的地址仓库不在同一个仓库中,有些可能在Github上,有些可能在Gitlab上。 所以我们需要配置Github的仓库的配置和Gitlab仓库的配置。 现在,我们来配置两个不同的仓库的地址。 假设&#xf…...

【Golang 面试 - 进阶题】每日 3 题(十三)

✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/UWz06 📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏…...

自定义线程池(二)

上节回顾 在上一节当中,已经实现了一个线程池,在本节当中,我们需要添加拒绝策略。这里使用到了策略模式的设计模式,因为拒绝策略是多种的,我们需要将这个权利下放给调用者(由调用者来指定我要采取哪种策略…...

【Linux】常见指令

目录 一、指令的理解二、Linux的目录结构三、XShell 下的热键四、shell命令以及运行原理五、Linux常见的指令汇总1. ls 指令1.1 常见的一些有关 ls 的别名1.2 隐藏文件或目录1.3 * 的匹配 2. pwd 指令3. cd 指令3.1 cd . . 指令 4. touch指令5. mkdir指令6. rmdir指令 &&am…...

uniapp自定义网格布局用于选择金额、输入框焦点事件以及点击逻辑实战

样式 <view class="withdraw-section"><text class="section-title">提现金额</text><view class="amount-options"><view v-for="(item, index) in list" :key="index" class="amount-opt…...

中小学创客室培养学生全面发展

随着时代的发展,教育也在飞速发展&#xff0c;教育决定着一个国家的未来&#xff0c;一个家庭的未来&#xff0c;一个人的未来&#xff0c;我国近年来大力鼓励科学教育&#xff0c;支持科学创新。因此&#xff0c;学校应该重视对学生的科学教育&#xff0c;尤其是处于思想启蒙阶…...

AI Agent智能体落地应用测试,一句话即可操控它执行工作

一、什么是Agent 在软件应用中&#xff0c;软件代理或智能代理&#xff0c;是一种能够自主执行任务或做出决策的计算机程序。它们可以用于自动化任务、个性化推荐、数据分析等&#xff0c;这一类的桌面应用称之为Agent。如Siri、Alexa、Google Assistant等&#xff0c;它们能够…...

免费的SD-WAN服务

SD-WAN&#xff0c;SASE&#xff0c;零信任是近年来比较火的概念&#xff0c;SD-WAN发展已经很久了&#xff0c;但是真正能够自主研发做SD-WAN的企业其实并不算太多。 比扬云的SD-WAN产品是自主研发的&#xff0c;可控性强&#xff0c;最重要的是具有免费版本&#xff0c;可以免…...

gradle安装及配置

文章目录 一、下载安装包二、解压文件三、环境变量配置四、验证安装结果五、配置国内源六、IDEA配置 一、下载安装包 从gradle官网下载安装包&#xff0c;官网地址为&#xff1a;https://gradle.org/releases/ 我们只需要下载编译好的文件即可。 二、解压文件 解压文件到指定…...

C-sharp-console-gui-framework:C#控制台应用程序的GUI框架

推荐一个.Net开源项目&#xff0c;方便我们基于控制台创建图形用户界面&#xff08;GUI&#xff09;应用程序。 01 项目简介 ConsoleGUI是一个简单的布局驱动.NET框架&#xff0c;用于创建基于控制台的GUI应用程序。 核心功能&#xff1a; **布局驱动&#xff1a;**与WPF或H…...

一文搞懂后端面试之MySQL MVCC【中间件 | 数据库 | MySQL | 隔离级别 | Read View】

为什么需要MVCC 锁本身就是用于并发控制的&#xff0c;那么为什么InnoDB还要引入MVCC&#xff0c;读写都加锁不就可以控制住并发吗&#xff1f; 锁确实可以&#xff0c;但是性能太差。如果是纯粹的锁&#xff0c;那么写和写、读和写、读和读之间都是互斥的。如果是读写锁&…...

Mysql执行计划(上)

1、执行计划的概念 执行计划是什么&#xff1a;使用EXPLAIN关键字可以模拟优化器执行SQL查询语句&#xff0c;从而知道MySQL是如何处理你的SQL语句的。 作用&#xff1a;分析你的查询语句或是表结构的性能瓶颈 语法&#xff1a;Explain SQL语句 执行计划输出内容介绍&#…...

使用Python+moviepy截取音频片段

一、使用AudioFileClip对象的subclip函数&#xff0c;截取1秒至3秒的音频 from moviepy.editor import *auAudioFileClip("/home/Download/test.mp3") # 创建对象clipau.subclip(1,3) # 截取1秒至3秒的音频clip.write_audiofile("/home/Download/clip.mp3"…...

Java学习Day19

动态SQL语句标签 1.if 用于根据条件判断是否包括某段 SQL 代码 <if test"checktext !null and check !"> 2.<choose>, <when>, <otherwise>类似于 Java 的 switch 语句&#xff0c;用于在多个条件中选择一个。 <select id"getSt…...

8.达梦数据库常用SQL

文章目录 前言1. 服务器资源1.1 CPU使用率1.2 内存使用率 2 数据库实例管理2.1 查询版本号2.2 查询ini配置2.3 查询归档配置2.4 数据库实例初始化参数2.5 查看数据库信息2.6 查看数据库实例信息2.7 查看数据库实例信息2.8 查看授权信息2.9 查询页大小&#xff0c;字符集大小2.1…...

深入理解接口测试:实用指南与最佳实践(四)IHRM管理系统实战-项目分析

​ ​ 您好&#xff0c;我是程序员小羊&#xff01; 前言 这一阶段是接口测试的学习&#xff0c;我们接下来的讲解都是使用Postman这款工具&#xff0c;当然呢Postman是现在一款非常流行的接口调试工具&#xff0c;它使用简单&#xff0c;而且功能也很强大。不仅测试人员会使用…...

程序编译及链接

你好&#xff01;感谢支持孔乙己的新作&#xff0c;本文就程序的编译及链接与大家分析我的思路。 希望能大佬们多多纠正及支持 &#xff01;&#xff01;&#xff01; 个人主页&#xff1a;爱摸鱼的孔乙己-CSDN博客 ​ ​ 1.翻译译环境与运行环境 当我们进行程序设计时&…...

route 命令介绍及使用方法

route 命令 作用&#xff1a;用于显示和操作 IP 路由表 &#xff08;show/manipulate the IP routing table&#xff09;。 在命令行下执行 route 命令添加路由&#xff0c;不会永久保存&#xff0c;当网卡重启或者机器重启后&#xff0c;该路由就会失效。 命令参数&#xf…...