C++ 设计模式——外观模式

外观模式

    • C++ 设计模式——外观模式
      • 主要组成部分
        • 1. 外观类(Facade)
        • 2. 子系统类(Subsystem)
        • 3. 客户端(Client)
      • 例一:工作流程示例
        • 1. 外观类(Facade)
        • 2. 子系统类(Subsystem)
        • 3. 客户端(Client)
        • UML 图
        • UML 图解析
          • 1. 外观类与子系统类的依赖
          • 2. 子系统类之间的独立性
          • 3. 客户端与外观类的依赖
      • 例二:工作流程示例
        • 1. 设备类
        • 2. 外观类(HomeTheaterFacade)
        • 3. 客户端(main 函数)
      • UML 图
      • UML 图解析
        • 1. 外观类与子系统类的依赖
        • 2. 子系统类之间的独立性
        • 3. 客户端与外观类的关系
      • 优缺点
      • 适用场景
      • 例一:完整代码
      • 例二:完整代码

C++ 设计模式——外观模式

外观模式(Facade Pattern)是一种结构性设计模式,它为复杂的子系统提供一个简单的接口。通过外观模式,客户端通过外观类与子系统进行交互,外观类将客户端的请求委托给适当的子系统对象,从而实现功能的调用。这样的设计隐藏了子系统的复杂性,使得客户端与子系统之间的耦合度降低。

引入“外观”设计模式的定义(实现意图):提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。

主要组成部分

1. 外观类(Facade)
  • 核心角色:外观类是外观模式的核心,提供一个统一的接口,简化客户端与子系统之间的交互。
  • 封装子系统:它封装了多个子系统类,对外提供高层次的接口,使得客户端无需直接与子系统交互。
  • 协调功能:外观类负责协调子系统对象的调用顺序,确保它们能够协同工作。
2. 子系统类(Subsystem)
  • 具体实现:子系统类实现系统的具体功能,通常由多个子系统类组成。
  • 独立性:每个子系统类独立于外观类,它们不需要了解外观类的存在。
  • 相互通信:子系统类之间可以相互通信,也可以被外观类调用。
3. 客户端(Client)
  • 简化交互:客户端使用外观类提供的接口与系统交互。
  • 隐藏细节:客户端不需要了解子系统的具体实现细节,只需与外观类进行交互。

例一:工作流程示例

以《魔兽世界》这款流行的网络游戏为例,其配置选项丰富多样,包括图形、声音和语音聊天等多个方面。每个方面都有详细的配置项。

1. 外观类(Facade)

conffacade 类是外观类,它提供了 LowConfComputerHighConfComputer 两个方法,分别用于配置低配置和高配置的电脑。它内部调用了多个子系统的实例,简化了客户端的调用。

//扮演外观模式角色的类
class conffacade
{//--------------单件类实现相关begin----------------
private:conffacade() {};conffacade(const conffacade& tmpobj);conffacade& operator = (const conffacade& tmpobj);~conffacade() {};
public:static conffacade& getInstance(){static conffacade instance;return instance;}//--------------单件类实现相关end----------------
public:void LowConfComputer() //对于低配置电脑,只开启一些低配置选项{graphic& g_gp = graphic::getInstance();g_gp.display(true); //全屏耗费资源更低g_gp.effect(false);g_gp.resolution(2);g_gp.antialiasing(false);sound& g_snd = sound::getInstance();g_snd.bgsound(false);g_snd.envirsound(false);g_snd.expsound(false);g_snd.setvolume(15);chatvoice& g_cv = chatvoice::getInstance();g_cv.micvolume(20);g_cv.micsens(50);g_cv.chatvolume(60);}void HighConfComputer() //对于高配置电脑,能达到最好效果的项全部开启{graphic& g_gp = graphic::getInstance();g_gp.display(false);g_gp.effect(true);g_gp.resolution(0);g_gp.antialiasing(true);sound& g_snd = sound::getInstance();g_snd.bgsound(true);g_snd.envirsound(true);g_snd.expsound(true);g_snd.setvolume(50);chatvoice& g_cv = chatvoice::getInstance();g_cv.micvolume(100);g_cv.micsens(100);g_cv.chatvolume(100);}
};
2. 子系统类(Subsystem)

每个子系统类(graphicsoundchatvoice)负责自己的特定功能。它们提供了具体的方法供外观类调用,执行实际的业务逻辑。

//图形相关类
class graphic
{//--------------单件类实现相关begin----------------
private:graphic() {};graphic(const graphic& tmpobj);graphic& operator = (const graphic& tmpobj);~graphic() {};
public:static graphic& getInstance(){static graphic instance;return instance;}//--------------单件类实现相关end----------------
public:void display(bool enable) //是否全屏显示(true:是){cout << "图形->是否全屏显示->" << enable << endl;//其他代码略......}void effect(bool enable)//是否开启特效(true:是){cout << "图形->是否开启特效->" << enable << endl;}void resolution(int index) //设置窗口分辨率{cout << "图形->分辨率设置选项->" << index << endl;}void antialiasing(bool enable)//是否开启抗锯齿(true:是){cout << "图形->是否开启抗锯齿->" << enable << endl;}//其他接口略......
};//声音相关类
class sound
{//--------------单件类实现相关begin----------------
private:sound() {};sound(const sound& tmpobj);sound& operator = (const sound& tmpobj);~sound() {};
public:static sound& getInstance(){static sound instance;return instance;}//--------------单件类实现相关end----------------
public:void bgsound(bool enable) //是否开启背景声音(true:是){cout << "声音->是否开启背景声音->" << enable << endl;}void envirsound(bool enable)//是否开启环境音效(true:是){cout << "声音->是否开启环境音效->" << enable << endl;}void expsound(bool enable) //是否开启表情声音(true:是){cout << "声音->是否开启表情声音->" << enable << endl;}void setvolume(int level) //音量大小设置(0-100){cout << "声音->音量大小为->" << level << endl;}//其他接口略......
};//语音聊天相关类
class chatvoice
{//--------------单件类实现相关begin----------------
private:chatvoice() {};chatvoice(const chatvoice& tmpobj);chatvoice& operator = (const chatvoice& tmpobj);~chatvoice() {};
public:static chatvoice& getInstance(){static chatvoice instance;return instance;}//--------------单件类实现相关end----------------
public:void micvolume(int level) //麦克风音量大小设置(0-100){cout << "语音聊天->麦克风音量大小为->" << level << endl;}void micsens(int level)//麦克灵敏度设置(0-100){cout << "语音聊天->麦克风灵敏度为->" << level << endl;}void chatvolume(int level) //聊天音量设置(0-100){cout << "语音聊天->聊天音量为->" << level << endl;}//其他接口略......
};
3. 客户端(Client)

main 函数中,客户端通过调用外观类的 LowConfComputerHighConfComputer 方法来配置电脑,而不需要了解各个子系统的内部实现。这种方式显著降低了复杂性。

int main() 
{conffacade& g_cffde = conffacade::getInstance();cout << "低配置电脑,调用LowConfComputer接口" << endl;g_cffde.LowConfComputer();cout << "------------------" << endl;cout << "高配置电脑,调用HighConfComputer接口" << endl;g_cffde.HighConfComputer();return 0;
}
UML 图

外观模式 UML 图1

UML 图解析
1. 外观类与子系统类的依赖
  • 外观类(conffacade)依赖于子系统类
    • conffacade 类内部需要调用 graphicsoundchatvoice 这三个子系统类的方法,以实现不同配置电脑的功能。
    • 例如,在 LowConfComputerHighConfComputer 方法中,外观类通过调用 graphic::getInstance()sound::getInstance()chatvoice::getInstance() 来获取各个子系统的实例,然后调用它们的方法。
2. 子系统类之间的独立性
  • 子系统类之间的独立性
    • 每个子系统类(如 graphicsoundchatvoice)是独立的,客户端和外观类并不直接依赖于它们的具体实现。
    • 这使得在未来需要修改或扩展某个子系统时,不会影响到客户端或外观类的其他部分。
3. 客户端与外观类的依赖
  • 客户端(main 函数)只依赖于外观类
    • 客户端通过外观类 conffacade 的实例来调用 LowConfComputerHighConfComputer 方法,而不需要直接与 graphicsoundchatvoice 等子系统类交互。
    • 这种设计减少了客户端与子系统之间的耦合,使得系统更易于维护和扩展。

例二:工作流程示例

在家庭影院系统中,多个设备(如屏幕、灯光、音箱、DVD播放器和游戏机)需要协同工作以提供良好的观影和游戏体验。使用外观模式,创建一个 HomeTheaterFacade 类。

1. 设备类

每个设备类都有 OnOff 方法,用于打开和关闭设备。简化这些设备的操作

//屏幕
class Screen
{
public:void On(){cout << "屏幕打开了!" << endl;}void Off(){cout << "屏幕关闭了!" << endl;}
};//灯光
class Light
{
public:void On(){cout << "灯光打开了!" << endl;}void Off(){cout << "灯光关闭了!" << endl;}
};//音箱
class Speaker
{
public:void On(){cout << "音箱打开了!" << endl;}void Off(){cout << "音箱关闭了!" << endl;}
};//DVD播放器
class DvdPlayer
{
public:void On(){cout << "DVD播放器打开了!" << endl;}void Off(){cout << "DVD播放器关闭了!" << endl;}
};//游戏机
class PlayerStation
{
public:void On(){cout << "游戏机打开了!" << endl;}void Off(){cout << "游戏机关闭了!" << endl;}
};
2. 外观类(HomeTheaterFacade)

HomeTheaterFacade 类提供了两个主要方法:WatchMoviePlayGame。这两个方法分别用于观看电影和玩游戏,内部调用相关设备的开关方法。

//家庭影院外观模式类
class HomeTheaterFacade
{
public:void WatchMovie() //看电影{//屏幕打开,灯光熄灭,音箱打开,DVD播放器打开,游戏机关闭。scnobj.On();lgobj.Off();spkobj.On();dpobj.On();psobj.Off();}void PlayGame() //玩游戏{//屏幕打开,灯光打开,音箱打开,DVD播放器关闭,游戏机打开。scnobj.On();lgobj.On();spkobj.On();dpobj.Off();psobj.On();}
private:Screen scnobj;Light lgobj;Speaker spkobj;DvdPlayer dpobj;PlayerStation psobj;
};
3. 客户端(main 函数)

main 函数中,客户端通过 HomeTheaterFacade 实例来调用 WatchMoviePlayGame 方法,简化了多个设备的操作。

int main()
{HomeTheaterFacade htfacobj;cout << "开始看电影---------------" << endl;htfacobj.WatchMovie();cout << "开始玩游戏---------------" << endl;htfacobj.PlayGame();return 0;
}

UML 图

外观模式 UML 图2

UML 图解析

1. 外观类与子系统类的依赖
  • HomeTheaterFacade 类:
    • 该类依赖于多个子系统类(ScreenLightSpeakerDvdPlayerPlayerStation)。它通过这些子系统类的实例来控制家庭影院的各个设备。
    • WatchMoviePlayGame 方法中,HomeTheaterFacade 调用这些子系统的 OnOff 方法来实现设备的开关操作。
2. 子系统类之间的独立性
  • 子系统类(ScreenLightSpeakerDvdPlayerPlayerStation):
    • 每个子系统类独立实现自己的功能,不依赖于其他子系统类。这种设计确保了每个设备的封装性和独立性,使得在未来的扩展中可以单独修改某个设备的实现,而不影响其他设备或外观类。
3. 客户端与外观类的关系
  • 客户端(main 函数):
    • 客户端通过 HomeTheaterFacade 的实例 htfacobj 调用 WatchMoviePlayGame 方法。客户端只依赖于外观类,而不需要直接与子系统类交互。
    • 这种依赖关系使得客户端的代码更为简洁,隐藏了系统的复杂性。

优缺点

优点

  • 简化接口:外观模式提供了一个统一的接口,使得子系统更加容易使用。
  • 降低耦合度:客户端与子系统之间的直接依赖关系减少,客户端只需与外观类交互。
  • 提高灵活性:当子系统发生变更时,只需要调整外观类的实现,而不需要修改客户端代码。
  • 易于维护:由于客户端与子系统解耦,系统的维护和扩展变得更加容易。

缺点

  • 违反开闭原则:如果增加新的子系统或者修改现有子系统的行为,可能需要修改外观类,这违反了开闭原则。
  • 可能导致设计过重:如果不恰当地使用外观模式,可能会导致系统出现大量细粒度的外观类,增加系统的复杂性。
  • 性能问题:在某些情况下,如果外观类需要处理多个子系统的交互,可能会引入额外的性能开销。

适用场景

  • 子系统复杂:当子系统非常复杂,客户端直接与子系统交互会非常困难时,可以使用外观模式。
  • 简化客户端调用:当需要提供一个简单的接口来隐藏系统的复杂性,让客户端不需要了解系统的内部细节时。
  • 构建层次结构:在构建多层结构的系统时,可以使用外观模式定义每一层的入口点,从而简化层与层之间的调用。
  • 解耦系统:当需要减少客户端与多个子系统之间的依赖关系,以降低系统耦合度时。
  • 逐步引入变化:当需要逐步引入新的子系统到现有系统中,而又不想影响现有客户端代码时,可以使用外观模式作为中间层逐步引入变化。

例一:完整代码

#include <iostream>
using namespace std;//图形相关类
class graphic
{//--------------单件类实现相关begin----------------
private:graphic() {};graphic(const graphic& tmpobj);graphic& operator = (const graphic& tmpobj);~graphic() {};
public:static graphic& getInstance(){static graphic instance;return instance;}//--------------单件类实现相关end----------------
public:void display(bool enable) //是否全屏显示(true:是){cout << "图形->是否全屏显示->" << enable << endl;//其他代码略......}void effect(bool enable)//是否开启特效(true:是){cout << "图形->是否开启特效->" << enable << endl;}void resolution(int index) //设置窗口分辨率{cout << "图形->分辨率设置选项->" << index << endl;}void antialiasing(bool enable)//是否开启抗锯齿(true:是){cout << "图形->是否开启抗锯齿->" << enable << endl;}//其他接口略......
};//声音相关类
class sound
{//--------------单件类实现相关begin----------------
private:sound() {};sound(const sound& tmpobj);sound& operator = (const sound& tmpobj);~sound() {};
public:static sound& getInstance(){static sound instance;return instance;}//--------------单件类实现相关end----------------
public:void bgsound(bool enable) //是否开启背景声音(true:是){cout << "声音->是否开启背景声音->" << enable << endl;}void envirsound(bool enable)//是否开启环境音效(true:是){cout << "声音->是否开启环境音效->" << enable << endl;}void expsound(bool enable) //是否开启表情声音(true:是){cout << "声音->是否开启表情声音->" << enable << endl;}void setvolume(int level) //音量大小设置(0-100){cout << "声音->音量大小为->" << level << endl;}//其他接口略......
};//语音聊天相关类
class chatvoice
{//--------------单件类实现相关begin----------------
private:chatvoice() {};chatvoice(const chatvoice& tmpobj);chatvoice& operator = (const chatvoice& tmpobj);~chatvoice() {};
public:static chatvoice& getInstance(){static chatvoice instance;return instance;}//--------------单件类实现相关end----------------
public:void micvolume(int level) //麦克风音量大小设置(0-100){cout << "语音聊天->麦克风音量大小为->" << level << endl;}void micsens(int level)//麦克灵敏度设置(0-100){cout << "语音聊天->麦克风灵敏度为->" << level << endl;}void chatvolume(int level) //聊天音量设置(0-100){cout << "语音聊天->聊天音量为->" << level << endl;}//其他接口略......
};//---------------------------------------------------
//扮演外观模式角色的类
class conffacade
{//--------------单件类实现相关begin----------------
private:conffacade() {};conffacade(const conffacade& tmpobj);conffacade& operator = (const conffacade& tmpobj);~conffacade() {};
public:static conffacade& getInstance(){static conffacade instance;return instance;}//--------------单件类实现相关end----------------
public:void LowConfComputer() //对于低配置电脑,只开启一些低配置选项{graphic& g_gp = graphic::getInstance();g_gp.display(true); //全屏耗费资源更低g_gp.effect(false);g_gp.resolution(2);g_gp.antialiasing(false);sound& g_snd = sound::getInstance();g_snd.bgsound(false);g_snd.envirsound(false);g_snd.expsound(false);g_snd.setvolume(15);chatvoice& g_cv = chatvoice::getInstance();g_cv.micvolume(20);g_cv.micsens(50);g_cv.chatvolume(60);}void HighConfComputer() //对于高配置电脑,能达到最好效果的项全部开启{graphic& g_gp = graphic::getInstance();g_gp.display(false);g_gp.effect(true);g_gp.resolution(0);g_gp.antialiasing(true);sound& g_snd = sound::getInstance();g_snd.bgsound(true);g_snd.envirsound(true);g_snd.expsound(true);g_snd.setvolume(50);chatvoice& g_cv = chatvoice::getInstance();g_cv.micvolume(100);g_cv.micsens(100);g_cv.chatvolume(100);}
};int main()
{    conffacade& g_cffde = conffacade::getInstance();cout << "低配置电脑,调用LowConfComputer接口" << endl;g_cffde.LowConfComputer();cout << "------------------" << endl;cout << "高配置电脑,调用HighConfComputer接口" << endl;g_cffde.HighConfComputer();           return 0;
}

例二:完整代码

//屏幕
class Screen
{
public:void On(){cout << "屏幕打开了!" << endl;}void Off(){cout << "屏幕关闭了!" << endl;}
};//灯光
class Light
{
public:void On(){cout << "灯光打开了!" << endl;}void Off(){cout << "灯光关闭了!" << endl;}
};//音箱
class Speaker
{
public:void On(){cout << "音箱打开了!" << endl;}void Off(){cout << "音箱关闭了!" << endl;}
};//DVD播放器
class DvdPlayer
{
public:void On(){cout << "DVD播放器打开了!" << endl;}void Off(){cout << "DVD播放器关闭了!" << endl;}
};//游戏机
class PlayerStation
{
public:void On(){cout << "游戏机打开了!" << endl;}void Off(){cout << "游戏机关闭了!" << endl;}
};//家庭影院外观模式类
class HomeTheaterFacade
{
public:void WatchMovie() //看电影{//屏幕打开,灯光熄灭,音箱打开,DVD播放器打开,游戏机关闭。scnobj.On();lgobj.Off();spkobj.On();dpobj.On();psobj.Off();}void PlayGame() //玩游戏{//屏幕打开,灯光打开,音箱打开,DVD播放器关闭,游戏机打开。scnobj.On();lgobj.On();spkobj.On();dpobj.Off();psobj.On();}
private:Screen scnobj;Light lgobj;Speaker spkobj;DvdPlayer dpobj;PlayerStation psobj;
};int main()
{HomeTheaterFacade htfacobj;cout << "开始看电影---------------" << endl;htfacobj.WatchMovie();cout << "开始玩游戏---------------" << endl;htfacobj.PlayGame();return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IT管理:我与IT的故事6--数字化建设规划工作坊圆满开展

在数字化浪潮席卷全球的时代背景下&#xff0c;企业的数字化转型已成为必然趋势。IT 部落精心打造的数字化规划实操工作坊顺利举办&#xff0c;为众多CIO的数字化转型之路点亮了明灯。 本次工作坊特别邀请到了业界知名的大咖讲师 Frank&#xff0c;他在数字化领域深耕多年&am…

【源码+文档+调试讲解】学院网站

摘 要 使用旧方法对冀中工程技师学院网站的信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在冀中工程技师学院网站的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题。这次…

Day23 第十站 文件IO的多路复用

#include <myhead.h>void insert_client(int *client_arr,int *len,int client) {//client_arr[n]{3,4} len&client_count,client_count2;//添加 5 client_arr[2(*len)]5(client)client_arr[*len]client;(*len); } int find_client(int *client_arr,int len,int clie…

Rembg.js - 照片去背景AI开发包

Rembg.js适用于为人物、建筑、电商产品等各种照片自动去除背景&#xff0c;可直接在浏览器内运行&#xff0c; 提供前端JavaScirpt二次开发接口。官方下载地址&#xff1a;Rembg.js图片去背景开发包 。 1、目录组织 Rembg.js开发包的目录组织说明如下&#xff1a; rembg …

RocketMQ源码分析 - 环境搭建

RocketMQ源码分析 - 环境搭建 环境搭建源码拉取导入IDEA调试1) 启动NameServer2) 启动Broker3) 发送消息4) 消费消息 环境搭建 依赖工具 JDK&#xff1a;1.8MavenIntellij IDEA 源码拉取 从官方仓库 https://github.com/apache/rocketmq clone或者download源码。 源码目录…

【题目/训练】:双指针

引言 我们已经在这篇博客【算法/学习】双指针-CSDN博客里面讲了双指针、二分等的相关知识。 现在我们来做一些训练吧 经典例题 1. 移动零 思路&#xff1a; 使用 0 当做这个中间点&#xff0c;把不等于 0(注意题目没说不能有负数)的放到中间点的左边&#xff0c;等于 0 的…

基于java的酒店管理系统设计与实现

系统分析与设计 需求分析 1.系统概要 根据餐饮系统的流程&#xff0c;完成从用户登录到开台点菜&#xff0c;到结账收银&#xff0c;到统计一条线的信息化管理&#xff0c;因此整个餐饮管理信息系统的研发内容就是开发一整套餐饮管理信息系统&#xff0c;实现餐饮业务的计算…

【Vue3】集成 Element Plus

【Vue3】集成 Element Plus 背景简介开发环境开发步骤及源码总结 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的…

后端开发刷题 | 合并两个排序的链表

描述 输入两个递增的链表&#xff0c;单个链表的长度为n&#xff0c;合并这两个链表并使新链表中的节点仍然是递增排序的。 数据范围&#xff1a; 0≤n≤1000&#xff0c;−1000≤节点值≤1000 如输入{1,3,5},{2,4,6}时&#xff0c;合并后的链表为{1,2,3,4,5,6}&#xff0c;…

MySQL各个版本root账号没有最高权限的解决方法

一、详细报错 ERROR 1045 (28000): Access denied for user ‘root’‘localhost’ (using password: YES) 报错原因&#xff08;分析过程&#xff09;&#xff1a; rootlocalhost用户密码修改导致 解决方法&#xff1a; 跳过权限验证启动数据库&#xff0c;并修改密码。如下…

怎么快速定位bug?如何编写测试用例?

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 作为一名测试人员如果连常见的系统问题都不知道如何分析&#xff0c;频繁将前端人员问题指派给后端人员&#xff0c;后端人员问题指派给前端人员&#xff0c;那么在…

独立站PrestaShop安装

独立站PrestaShop安装 独立站PrestaShop安装系统需求下载PrestaShop浏览器下载命令行下载 解压PrestaShop创建数据库移动PrestaShop源码到web目录composer安装依赖包nginx配置访问域名进入安装页面选择语言许可协议系统兼容性店铺信息Content of your store系统配置数据库店铺安…

数据结构day03(栈 Stack 顺序栈、链式栈 )内含具体详细代码实现

目录 【1】栈 Stack 1》栈的定义 2》顺序栈 2》链式栈 4》顺序栈的链式栈的区别 【1】栈 Stack 1》栈的定义 栈&#xff1a;是只允许在一端进行插入或删除的线性表&#xff0c;首先栈是一种线性表&#xff0c;但限定这种线性表只能在某一端进行插入和删除操作。 栈顶&…

仿照ContentLoadingProgressBar 的特点在Android项目中自定义Loading对话框

ContentLoadingProgressBar 是 Android 中的一个控件&#xff0c;继承自 ProgressBar。它在 ProgressBar 的基础上添加了一些特殊功能&#xff0c;主要用于在加载内容时显示进度。它的一些主要特点如下&#xff1a; 自动隐藏和显示&#xff1a;ContentLoadingProgressBar 会在…

JavaScript_7_练习:随机抽奖案例

效果图 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>练习&#xff1a;随机抽奖案例</tit…

vue项目配置基础路由vue-router

1、运行以下命令安装vue-router yarn add vue-router 2、在src目录下的components中新建两个vue页面 3、在src目录下新建router文件夹&#xff0c;在router文件夹下面新建index.js文件 4、配置main.js文件 //引入Vue import Vue from "vue"; //引入App import App…

全新分支版本!微软推出Windows 11 Canary Build 27686版

已经很久没有看到 Windows 11 全新的分支版本了&#xff0c;今天微软发布 Windows 11 Canary 新版本&#xff0c;此次版本号已经转移到 Build 27xxx&#xff0c;首发版本为 Build 27686 版。 此次更新带来了多项改进&#xff0c;包括 Windows Sandbox 沙盒功能切换到 Microsof…

LearnOpenGL——SSAO学习笔记

LearnOpenGL——SSAO学习笔记 SSAO一、基本概念二、样本缓冲三、法向半球四、随机核心转动五、SSAO着色器六、环境遮蔽模糊七、应用SSAO遮蔽因子 SSAO 一、基本概念 环境光照是我们加入场景总体光照中的一个固定光照常量&#xff0c;它被用来模拟光的散射(Scattering)。散射应…

QT事件机制理解

事件和信号 从硬件层来看: 事件就是一种中断&#xff0c; 中断的产生形式: 1.用户操控硬件所产生的中断。 2.由系统自身所产生的中断&#xff0c;比如说定时器。 这种中断由系统内核监控&#xff0c;由系统内核接收到中断并向CPU发出的执行请求就叫信号。所以说事件是信号产生…

C++,std::bind 详解

文章目录 1. 概述2. 基本用法2.1 使用占位符2.2 示例 3. 总结 1. 概述 std::bind 是 C11 引入的一个功能&#xff0c;它允许你将函数&#xff08;或成员函数、函数对象&#xff09;与其参数绑定&#xff0c;生成一个新的可调用对象。这个功能在需要将函数及其参数一起传递给其…