设计模式

本文主要介绍设计模式的主要设计原则和常用设计模式。

一、UML画图

1.类图

image-20230814220944426

2.时序图

image-20230814221009623

二、设计模式原则

1.单一职责原则

就是一个方法、一个类只做一件事;

2.开闭原则

就是软件的设计应该对拓展开放,对修改关闭,这在java中体现最明显的就是访问控制修饰符;

3.里式替换原则

就是在设计父子关系时,就是如果能用子类,则一定也能用父类替代;

4.接口隔离

每个接口的设计要高内聚,低耦合;

5.迪特米原则

这个也叫最小知道原则,就是设计一个类的时候,要保证这个对象知道的最小;

6.依赖倒置原则

主要是为了解决类之间的耦合性,这个在spring中体现的很详细,就是类间的依赖通过接口来实现;

三、常用设计模式

设计模式分为三种类型,共23种:

  1. 创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。

  2. 结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。

  3. 行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、责任链模式、访问者模式。

创建型模式

1.原型模式(singleton)

1) 概述

解决问题:在系统中其实只需要该类的一个对象,为避免频繁创建和销毁其他对象,只给该类一个单例对象供使用;

解决方法:给该类一个全局静态变量来保存单例,只提供一个共有方法来获取该实例,不提供构造方法来实例化对象;

使用场景:1.只需要一个全局实例的,比如说生产全局UUID的生成器;

2) 具体说明

  • 普通模式:重点注意由于只有一个实例化对象,所以实例变量是静态成员变量;再就是构造方法要是private修饰,排除new方法创建新的对象;还有就是创建实例对象的方法要是public static,这样才能通过类名直接创建;

    image-20230814221059150

  • 饿汉式:就是创建一个静态常量作为实例,这样类一加载就完成了实例对象的初始化操作;劣势也很明显,就是没法懒加载,但后面没有用到该单例时候也被加载进来的了;

  • 懒汉式:就是在调用getInstance()方法时才实例出单例对象,并且之前创建单例模式的方法都没有考虑到并发情况,当同时进入到getInstance()创建实例时候,没有办法保证只创建一个实例,所以动用synchronized和volatile关键字来保证方法的调用并发执行;

  • 双重检验式:在创建单例之前判断单例是否存在,再进入加锁阶段,和懒汉式有区别的是加锁阶段后还会再次判断是否单例存在,这是生产环境常用的模式。

  • IoDH方式:就是通过内部静态类的方式来避免懒汉式类加载的时候就创建了实例的问题;

3) 代码实现

/**
 * @author yangnk
 * @desc
 * @date 2023/08/13 16:46
 **/
public class Singleton {
    //volatile 保障可见性
    private volatile static Singleton singleton;

    //private构造方法,无法通过new来实例化对象
    private Singleton() { }

    public static Singleton getSingleton() {
        if (singleton == null) {
            //用synchronized加锁,只允许并发情况下进行一个实例化操作
            synchronized (Singleton.class) {
                //需要再次判断singletonTest == null,避免指令重排导致初始化和分配内存失序
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            Singleton singleton = Singleton.getSingleton();
            System.out.println("singletonTest.hashCode() = " + singleton.hashCode());
        }
    }
}

4) 总结

优点:1、只有一个对象在内存中,不用占用过多堆内存;2、只有一个实例,可以严格控制访问控制;

缺点:1、违法类设计模式的单一指责的原则,一个实例就能做好所有的事?肯定不行;

2.工厂模式(factory)

1) 概述

解决问题:将产品实例的创建过程封装在工厂类中实现,将产品的声明和创建分离开来,提供统一的接口来创建不同的产品实例,解决需要创建多种继承同一接口的产品;

解决方法:每个产品实现同一抽象产品类,每个工厂类实现同一抽象工厂类,通过多态特性实现不同的产品由不同的产品工厂类来实现;

使用场景:工厂设计模式在各大框架中是运用最多的,在自己之前写过的代码中,日志记录也用到了这种设计模式,他可以拓展其他记录日志的方式;再通过反射和配置的形式,可以做到不需要修改代码就能实现不同记录日志的功能;

2) 具体说明

**主要角色:**
  • 抽象工厂类:声明了一组用于创建产品对象的方法,每个方法对应一种产品类型。抽象工厂可以是接口或抽象类。

  • 具体工厂类:生产具体产品的类,实现了抽象工厂类;

  • 抽象产品类:是具体产品类的父类,封装了具体产品的方法;

  • 具体产品类:实现具体方法,实现了抽象产品类;

    几种不同的工厂模式:

  • 简单工厂模式:工厂方法的思路是通过工厂类来创建相应的实体对象,简单工厂的逻辑是具体产品类实现抽象或接口产品类的方法,外部想要使用该产品需要通过工厂类来获取,该类工厂模式通过判定来生产相应的具体产品类;

    image-20230814221441153

  • 抽象工厂模式:当碰到所需生产的具体产品太多的时候,它只需要实现相应的具体产品类,但是在工厂类中,他是需要修改代码来实现的,这就违背了设计模式修改闭合的原则,所以借鉴产品类有抽象或接口的思路,工厂类也有相应的抽象类或接口,如果新增了具体产品,就新增相应产品工厂类。

    image-20230814221457450

3) 代码实现

4) 总结

优势:1、向用户隐藏了产品生产的逻辑,符合Java良好封装性的特征;2、如果想要再加新的产品类,不需要修改其他代码,只需要实现他们的接口就好了;

劣势:1、如果产品很多那就很麻烦了,所以工厂模式不太适合产品超过5个的设计;

3.原型模式(prototype)

1) 概述

  • 模式定义:允许通过拷贝原始对象的属性创建一个相同的对象,而不需要关注这个对象怎么创建的。

  • 解决问题:不需要关注怎么创建一个新的对象。

  • 解决方案:在Java中年通过实clone()方法,在Spring中通过声明bean为Prototype类型来实现。

  • 应用场景:通过Java中的clone方法可以根据模板对象克隆一个原型对象,这就是原型模式的应用。在使用原型模式的时候要着重关注浅克隆还是深克隆。比较适合创建一个实例化比较复杂的时候,比如创建网络链接或数据库连接; 原型创建的对象一般会缓存起来,在运行时在缓存中获取即可。

2) 具体说明

原型的设计模式在于系统中有一个原型实例,之后在需要只需要**复制**他的副本就好了。原型设计模式最初由原型抽象类和原形实现类组成,其中最关键的在于要实现原型副本的拷贝,在Java中这是很容易实现的,直接重写clone方法就好了,但这个要注意Java里的深复制和浅复制,如果成员变量有对象的话,需要实现通过流来实现深复制。之后原型进化出另外一个组件,是原型管理器,其将原型保存到一个map中,等到其他类需要的话,再从这个map中拷贝。

![image-20230814221512615](https://img-blog.csdnimg.cn/13afef1af3ae460ea6f577b13f0b0f2d.png)

3) 代码实现

4) 总结

优势:提高实例化对象的性能,不需要关注构造函数和初始化的过程,一般创建好的原型对象会放在缓存中,后续直接从缓存中获取对象即可 。

劣势:如果类的成员变量引用比较深的话,那样clone起来就比较麻烦了;



参考资料:深度分析:java设计模式中的原型模式,看完就没有说不懂的:https://segmentfault.com/a/1190000023831083

4.构建者模式(Builder)

1) 概述

  • 解决问题:当实例化一个对象的时,需要配置多个参数,并且参数的组合类型还非常多的情况,可以考虑使用使用构建者模式。
  • 解决方案:通过Builder统一给需要的对象来进行构建。
  • 应用场景:应用于一个实例需要通过配置 多个参数才能构建,并且这样的参数搭配有很多种,这种情况可以将产品本身和产品的创建解耦,产品的创建就交给builder来实现,实践中一般构造函数中的参数超过4个就可以考虑使用构建者模式了;

2) 具体说明

构建者模式讲的是这样一件事,就是如果一个实例有很多类组件或属性共同组成,而且没有固定套路,这样的的组合有很多种,所以就需要一种套餐的形式去构建,就像kfc套餐一样,汉堡和饮料作为套餐,具体类别你可以再选择;

构建者模式有三大组件,包括builder接口类、builder实现类还有director。他们的逻辑关系是这样的,builder实现类负责组合各类产品,最合成一个套餐,这个套餐其实在他的接口中就已经制定好了,而director就负责构建这样一个套餐;

image-20230814221537720

3) 代码实现

简单构建者模式的实现:
public class Computer {
    private final String cpu;//必须
    private final String ram;//必须
    private final int usbCount;//可选
    private final String keyboard;//可选
    private final String display;//可选

    private Computer(Builder builder){
        this.cpu=builder.cpu;
        this.ram=builder.ram;
        this.usbCount=builder.usbCount;
        this.keyboard=builder.keyboard;
        this.display=builder.display;
    }

    public static class Builder{
        private String cpu;//必须
        private String ram;//必须
        private int usbCount;//可选
        private String keyboard;//可选
        private String display;//可选

        public Builder(String cup,String ram){
            this.cpu=cup;
            this.ram=ram;
        }

        public Builder setUsbCount(int usbCount) {
            this.usbCount = usbCount;
            return this;
        }
        public Builder setKeyboard(String keyboard) {
            this.keyboard = keyboard;
            return this;
        }
        public Builder setDisplay(String display) {
            this.display = display;
            return this;
        }
        public Computer build(){
            return new Computer(this);
        }
    }
}

4) 总结

优势:针对很多参数组成的实例,将对象的构建和使用分离,能够非常灵活的构建一个对象;

劣势:1.他有一定的局限性,就是builder的实例是同一个类别的,或者说他是实现同一个接口的;2.使用构建者模式进行对象创建适合参数比较多得情况,参数较少不建议使用;

参考资料:秒懂设计模式之建造者模式(Builder pattern) shusheng007:https://zhuanlan.zhihu.com/p/58093669

结构性模式

5.适配器模式(adapter)

1) 概述

  • 解决问题:已有的对象和需要的对象无法直接对接,需要通过适配器来进行中转适配。

  • 解决方案:适配器继承或者依赖适配者,在适配器中实现需要提供的功能;

  • 使用场景:适配器类的使用场景还是很广的, 在SpringMVC中就有广泛的使用,比如Handler和HandlerAdapter的关系;

2) 具体说明

主要角色:

  • 适配器接口类:规定适配器需要实现的接口方法;
  • 适配器类:为目标类实现功能匹配的类;
  • 适配者接口类:目标类,原始还未适配的类的接口;
  • 适配者类:目标类的实现类;

适配器模式是利用一个适配器类来将接口无法适配的类对接起来。常用组件是一个适配器类和一个适配器接口类外加一个适配者类,适配者类上面可以有个是适配者类接口,要做的就是外部通过适配器就能够直接调用适配者的方法,具体实现是适配器类实现适配接口类的方法,适配器类接口种定义了外部需要的接口,适配器类可以继承适配者,这样就能从其身上继承他的方法,另一种方式是组合适配者对象引用。总的来说,适配器模式的关键在于实现他的适配器接口类,继承适配者类。他的UML类图如下所示:

image-20230814221717048

3) 代码实现

4) 总结

  • 优势:1、可以通过一个适配器适配多个适配者,这样可以弥补前期设计没有考虑周全的问题; 

  • 劣势: 加了中间一层适配器类转发,导致代码关系变复杂了;

一文彻底弄懂适配器模式(Adapter Pattern):https://segmentfault.com/a/1190000040524953

6.装饰者模式(decorator)

1) 概述

  • 解决问题:在不改变目标类的前提下拓展功能。

  • 解决方案:通过将目标类包装在修饰器内,在能够实现目标类的功能同时,修饰器类也能拓展其他功能;

  • 应用场景:装饰者设计模式在Java IO中运用的十分普遍,为什么在IO中引用普遍呢?在于IO为了兼顾不同应用场景和需求有太多不同类型的IO流了,所以利用修饰者模式的话,只需要在基础IO流上进行功能补充就好了;

2) 具体说明

主要组件:
  • 构建接口:目标类的接口类,定义目标类需要实现的功能;

  • 具体构建类:构建接口的具体实现;

  • 修饰器接口:持有对构建类的引用,并实现了构建接口的方法,能够统一对外提供目标类的方法;

  • 具体修饰器类:实现了修饰器接口,作为修饰器具体实现类还会新增其他功能;

修饰者模式又称为包装器模式,出现的原因在于有在基础类上进行增加功能的需求,如果直接修改当然违背了对修改闭合的原则,所以就想出了在原本的类上新增特性的修饰者类。实现该种模式的逻辑是:原始的被目标类实现对应的接口,修饰者也实现这个接口,当然这不是真正的修饰者类,其真正的修饰者类继承了修饰者接口,将其补充功能在真正的修饰者类中实现。

image-20230814222021637

3) 代码实现

4) 总结

  • 优势:1、修饰者是类似于继承的一种增强其他类的一种方式,但是他更灵活,要增加什么功能可以自己增加;2、通过配置和运行时动态生成的方式,可以让他变得更灵活;

  • 劣势:变复杂了;

7.门面模式(facade)

1) 概述

解决问题:访问系统中存在多个子系统,访问起来非常复杂;

解决方案:为客户端提供一个统一的门面类型,之后只需要访问门面即可访问子系统中方法;

使用场景:Spring的日志框架中用到了,slf4j统一了丰富多样的日志实现;

2) 具体说明

主要角色:

  • 门面类:通过门面统一向外界提供服务;

  • 子系统接口:规定子系统需要实现的逻辑;

  • 子系统类:实现子系统接口,实现各自的业务逻辑;

    门面模式又称外观模式,用以解决在多个外部系统要和多个内部系统进行通信,可能存在非常多的联系,提升系统交互的复杂度,通过引入门面统一负责和外部系统的通信,减少系统的复杂程度;在门面模式中存在门面和子系统两个角色。

image-20230814222037023

3) 代码实现

4) 总结

优点:1.化繁为简,将对多个不同的子系统访问转换为会单个门面的访问;

缺点:1.违反了开闭原则,组件间相互依赖,修改子系统会涉及修改门面 ;

8.代理模式(proxy)

1) 概述

解决问题:通过代理类来实现对委托类的操作,可以出现在委托类无法获得或者不便获得,也可以用以增强对委托类的操作;

解决方案:JDK和Spring源码中有很多实现;

2) 具体说明

主要角色:

  • 委托者接口:定义目标类需要实现的方法;

  • 委托者实现:具体实现委托类中的方法;

  • 代理者:代理类中有委托类的引用,在代理类中也需要实现委托类的方法,所以可以执行委托类的本身的方法外,除此之外还能够在该方法前后进行增加;

代理模式有3个组件,包括:委托者接口、委托者还有代理者,他们的关系是:定义一个委托者接口,委托者和代理者都要实现他的方法,在代理类中还需要创建委托者的对象引用,这样在对委托者类方法进行重写时候可以直接调用。动态代理的UML类图:

image-20230814222049512

代理模式经常用在(1)委托类不想被直接调用,可以通过调用他的代理类来实现,像房产中介一样;(2)还有一种情况是可以增强委托类的能力,像Java中的动态代理,这中在spring aop中应用广泛;

3) 代码实现

4) 总结

优势:降低调用者和被调用者的耦合关系,怎么说呢?就是被调用者想要拓展新功能,可以在代理类中实践,不需要在自身类中进行修改,符合设计模式的开闭原则;

劣势:1对于JDK的动态代理,他需要委托类有接口,通过CgLib来动态代理,可以不需要;

行为型模式

9.责任链模式(chain of responsibility)

1) 概述

解决问题:一条处理链中的每个角色都能够处理请求,避免请求方和相应方的耦合关系,沿着这条处理链处理请求,直到最后处理得到结果。

使用场景:Spring的Filter中使用了责任链,这个适合于可以进行一系列链式处理的场景;

2) 具体说明

对于处理流程是线性的比较合适,每个handler中包含目前节点需要处理的业务,也包括下一个节点的引用。

image-20230814222100266

3) 代码实现

4) 总结

10.观察者模式(Observer)

1) 概述

2) 具体说明

观察者模式又称订阅发布模式,所以他适合发布订阅的场景,当目标对象有事件发生,就会通知观察者。

image-20230814222110225

3) 代码实现

4) 总结

四、代码实现

GitHub:https://github.com/yangnk/MyComputerScience/tree/07f4ea1e6c06437ba5fa552a288e67a1adae3cf9/src/main/java/designPattern

TODO

  1. 需要完善已经写的设计模式;
  2. 需要补充新的还未加上的设计模式;

参考资料

  1. 类图、时序图怎么画:https://design-patterns.readthedocs.io/zh_CN/latest/read_uml.html#id2

  2. 设计模式gitbook上的一本书,讲的很好:https://gof.quanke.name

  3. 菜鸟教程上的教程:http://www.runoob.com/design-pattern/design-pattern-tutorial.html

本文由博客一文多发平台 OpenWrite 发布!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

spring详解

spring是于2003年兴起的一款轻量级的&#xff0c;非侵入式的IOC和AOP的一站式的java开发框架&#xff0c;为简化企业级应用开发而生。 轻量级的&#xff1a;指的是spring核心功能的jar包不大。 非侵入式的&#xff1a;业务代码不需要继承或实现spring中任何的类或接口 IOC&…

Spring5学习笔记—AOP编程

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; Spring专栏 ✨特色专栏&#xff1a; M…

国企的大数据岗位方向的分析

现如今大数据已无所不在&#xff0c;并且正被越来越广泛的被应用到历史、政治、科学、经济、商业甚至渗透到我们生活的方方面面中&#xff0c;获取的渠道也越来越便利。 今天我们就来聊一聊“大屏应用”&#xff0c;说到大屏就一定要聊到数据可视化&#xff0c;现如今&#xf…

eclipse 导入项目js报错问题

eclipse 导入项目后会出现项目中的js文件报错&#xff08;红叉&#xff09;&#xff0c;如下图所示&#xff0c;有时候报错的文件很多&#xff0c;需要集中处理。 解决办法&#xff1a; 右键项目名称》Properties》MyEclipse》JavaScript》Include Path&#xff0c;在右侧选择“…

linux 文件权限识别及其修改

一、文件权限认识 在 Linux 系统中&#xff0c;一切皆文件&#xff0c;目录也是一种文件形式叫目录文件&#xff0c;它们的属性主要包含&#xff1a;索引节点(inode)&#xff0c;类型、权限属性、链接数、所归属的用户和用户组、最近修改时间等内容。 如下为根目录下目录&…

基于OpenCV的人脸识别和模型训练系统(万字详解)

前言 我们身边的人脸识别有车站检票&#xff0c;监控人脸&#xff0c;无人超市&#xff0c;支付宝人脸支付&#xff0c;上班打卡&#xff0c;人脸解锁手机。 人脸检测是人脸识别系统组成的关键部分之一&#xff0c;其目的是检测出任意给定图片中的包含的一个或多个人脸&#…

网络通信原理IP头部格式(第四十二课)

字段作用解析:1)版本: 指的IP地址的版本 (IPv4 或 IPV6)2)首部长度: 次数据包的首部长度一共是多少,没有加可选项3)优先级与服务类型:表示****数据包是否需要优选传递4)总长度: 表示的是整个数据包的大小,也就****是首部+数据5)标识符、标志、段偏移量:的作用将拆开的…

ts与vue

ts与Vue 如果你已经学习了typeScript,但不知道如何在vue项目中使用&#xff0c;那么这篇文章将会很适合你。参考千峰教育 kerwin视频 1.会自动推导&#xff0c;隐士推导。提示 类型系统。 独立模块。 isolatedModules选项&#xff1a;是否配置为独立的模块。 减少报错 let …

Springboot项目启动后按顺序加载自定义类 (demo)

1. 实现ApplicationRunner接口, 重写run方法 import lombok.extern.slf4j.Slf4j; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.core.annotation.Order; import org.springframewor…

IDEA项目实践——JavaWeb简介以及Servlet编程实战

系列文章目录 IDEA项目实践——创建Java项目以及创建Maven项目案例、使用数据库连接池创建项目简介 IDEWA项目实践——mybatis的一些基本原理以及案例 IDEA项目实践——动态SQL、关系映射、注解开发 IDEA项目实践——Spring框架简介,以及IOC注解 IDEA项目实践——Spring当…

mysql 03.查询(重点)

先准备测试数据&#xff0c;代码如下&#xff1a; -- 创建数据库 DROP DATABASE IF EXISTS mydb; CREATE DATABASE mydb; USE mydb;-- 创建student表 CREATE TABLE student (sid CHAR(6),sname VARCHAR(50),age INT,gender VARCHAR(50) DEFAULT male );-- 向student表插入数据…

好用的安卓手机投屏到mac分享

工具推荐&#xff1a;scrcpy github地址&#xff1a;https://github.com/Genymobile/scrcpy/tree/master mac使用方式 安装环境&#xff0c;打开terminal&#xff0c;执行以下命令&#xff0c;没有brew的先安装brew brew install scrcpy brew install android-platform-too…

运营商三要素 API:构建安全高效的身份验证系统

当今数字化的世界中&#xff0c;身份验证是各行各业中至关重要的一环。为了保护用户的隐私和数据安全&#xff0c;企业需要寻求一种既安全可靠又高效便捷的身份验证方式。运营商三要素 API 应运而生&#xff0c;为构建安全高效的身份验证系统提供了有力的解决方案。 运营商三要…

【卷积神经网络】卷积,池化,全连接

随着计算机硬件的升级与性能的提高&#xff0c;运算量已不再是阻碍深度学习发展的难题。卷积神经网络&#xff08;Convolution Neural Network&#xff0c;CNN&#xff09;是深度学习中一项代表性的工作&#xff0c;CNN 是受人脑对图像的理解过程启发而提出的模型&#xff0c;其…

【C++学习手札】一文带你认识C++虚函数(内层剖析)

食用指南&#xff1a;本文在有C基础的情况下食用更佳 &#x1f340;本文前置知识&#xff1a; C初识继承 ♈️今日夜电波&#xff1a;No title —REOL 1:02 ━━━━━━️&#x1f49f;──────── 4:03 …

微服务中间件--微服务保护

微服务保护 微服务保护a.sentinelb.sentinel限流规则1) 流控模式1.a) 关联模式1.b) 链路模式 2) 流控效果2.a) 预热模式2.b) 排队等待 3) 热点参数限流 c.隔离和降级1) Feign整合Sentinel2) 线程隔离2.a) 线程隔离&#xff08;舱壁模式&#xff09; 3) 熔断降级3.a) 熔断策略-慢…

基于Servlet实现的管理系统(包含服务器源码+数据库)

资料下载链接 介绍 基于Servlet框架的管理系统 简洁版 &#xff1b; 实现 登录 、 注册 、 增 、 删 、 改 、 查 &#xff1b; 可继续完善增加前端、校验、其他功能等&#xff1b; 可作为 Servlet项目 开发练习基础模型&#xff1b; 课程设计 、 毕业设计 开发基础&…

java-垃圾回收与算法

垃圾回收与算法 1. 如何确定垃圾 1. 引用计数法 在 Java 中&#xff0c;引用和对象是有关联的。如果要操作对象则必须用引用进行。因此&#xff0c;很显然一个简单的办法是通过引用计数来判断一个对象是否可以回收。简单说&#xff0c;即一个对象如果没有任何与之关联的引用&…

基于YOLOv5n/s/m不同参数量级模型开发构建茶叶嫩芽检测识别模型,使用pruning剪枝技术来对模型进行轻量化处理,探索不同剪枝水平下模型性能影响【续】

这里主要是前一篇博文的后续内容&#xff0c;简单回顾一下&#xff1a;本文选取了n/s/m三款不同量级的模型来依次构建训练模型&#xff0c;所有的参数保持同样的设置&#xff0c;之后探索在不同剪枝处理操作下的性能影响。 在上一篇博文中保持30的剪枝程度得到的效果还是比较理…

Qt平滑弹出页面

目标功能&#xff1a; (1)按下btn&#xff0c;弹出绿色页面。 (2)按下btn2,绿色页面隐藏。 (3)按下左边余下的区域&#xff0c;绿色页面也隐藏。 (4)平滑地显示和隐藏 效果&#xff1a; form.h #ifndef FORM_H #define FORM_H#include <QWidget>namespace Ui { class…
最新文章