手机可以使用wordpress/西安seo网站建设

手机可以使用wordpress,西安seo网站建设,武汉人才网官方网站,wordpress+ie9一、装饰模式基本介绍 装饰模式(Decorator Pattern)是一种结构型设计模式,允许你在不改变对象自身的基础上,动态地给一个对象添加额外的职责。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签…

一、装饰模式基本介绍

装饰模式(Decorator Pattern)是一种结构型设计模式,允许你在不改变对象自身的基础上,动态地给一个对象添加额外的职责。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。其核心思想是动态地为对象添加额外职责,且不改变原有类的结构。它通过组合而非继承实现功能扩展,解决了继承体系中因功能叠加导致的子类爆炸问题。

1.1 模式诞生背景

假设需要为手机添加挂件、贴膜等功能,若采用继承方式会产生大量组合子类(如iPhoneWithCase、NokiaWithSticker等)。装饰模式通过将功能模块化,允许运行时动态组合,使系统更灵活。

1.2 核心特点

动态扩展:运行时添加或删除功能;
避免继承缺陷:减少子类数量(N+M代替N*M);
遵循开放-封闭原则:扩展开放,修改封闭;

二、内部原理与结构解析

2.1 模式内部角色划分

  • Component(抽象组件):定义一个抽象接口,规定了被装饰对象和装饰器对象的共同行为;
  • ConcreteComponent(具体组件):实现抽象组件接口的基础功能,是被装饰的具体对象;
  • Decorator(抽象装饰器):继承Component,持有一个抽象组件Component对象的引用,并实现抽象组件接口,其目的是为具体装饰器提供统一的接口;
  • ConcreteDecorator(具体装饰器):继承自抽象装饰器,负责给具体组件添加额外的职责,以及具体的功能;

2.2 关键实现原理

// 抽象组件:手机接口 
class Phone {
public:virtual void show() = 0;virtual ~Phone() {}
};// 具体组件:iPhone基础款 
class iPhone : public Phone {
public:void show() override { cout << "基础版iPhone" << endl; }
};// 抽象装饰器 
class PhoneDecorator : public Phone {
protected:Phone* phone;  // 核心:持有组件对象 
public:PhoneDecorator(Phone* p) : phone(p) {}void show() override { phone->show(); }
};// 具体装饰器:手机壳装饰 
class CaseDecorator : public PhoneDecorator {
public:CaseDecorator(Phone* p) : PhoneDecorator(p) {}void show() override {PhoneDecorator::show();addCase();}
private:void addCase() { cout << " + 透明手机壳" << endl; }
};

三、典型应用场景

3.1 动态功能扩展

当你需要在运行时为对象动态添加功能,而不是在编译时就确定对象的功能时,可以使用装饰模式。例如,在图形界面编程中,为一个窗口动态添加滚动条、标题栏等功能。

  • UI控件增强:为按钮添加边框、阴影等视觉效果;
  • 流处理系统:对数据流动态添加加密、压缩等功能;

3.2 多层功能叠加

当多个对象需要共享一些功能时,可以将这些功能封装成装饰器,多个对象可以使用这些装饰器来获得相同的功能。例如,在一个日志系统中,多个类可能需要记录日志,将日志记录功能封装成装饰器,多个类可以使用这个装饰器来实现日志记录功能。

  • 日志系统:基础日志输出 + 时间戳 + 线程ID标记;
  • 支付系统扩展:基础支付流程 + 风控校验 + 优惠券抵扣;

3.3 替代多层继承

如果使用继承来扩展对象的功能,可能会导致子类数量过多,形成子类爆炸的问题。装饰模式可以通过组合的方式来扩展对象的功能,避免了子类的大量创建。例如,在一个游戏中,角色有不同的技能和装备,如果使用继承来实现不同技能和装备的组合,会产生大量的子类;而使用装饰模式,可以在运行时动态为角色添加技能和装备。

  • 跨平台文本渲染:基础文本渲染 + 字体特效 + 多语言支持;
  • 游戏角色装备:基础角色属性 + 武器/护甲加成;

四、使用方法与实现步骤

4.1 标准实现流程(以游戏武器系统为例)

步骤1:定义抽象组件

class Weapon {
public:virtual int getDamage() = 0;virtual ~Weapon() {}
};

步骤2:实现具体组件

class Sword : public Weapon {
public:int getDamage() override { return 50; }
};

步骤3:定义抽象装饰器

class WeaponDecorator : public Weapon {
protected:Weapon* weapon;
public:WeaponDecorator(Weapon* w) : weapon(w) {}int getDamage() override { return weapon->getDamage(); }
};

步骤4:实现具体装饰器

// 火焰附魔装饰 
class FireEnchant : public WeaponDecorator {
public:FireEnchant(Weapon* w) : WeaponDecorator(w) {}int getDamage() override {return weapon->getDamage() + 20;}
};// 锋利的宝石装饰 
class SharpGem : public WeaponDecorator {
public:SharpGem(Weapon* w) : WeaponDecorator(w) {}int getDamage() override {return weapon->getDamage() + 15;}
};

步骤5:客户端组合使用

Weapon* sword = new Sword();
sword = new FireEnchant(sword);  // 叠加火焰附魔 
sword = new SharpGem(sword);     // 再叠加锋利宝石 cout << "总攻击力:" << sword->getDamage();  // 输出 

五、常见问题与解决方案

5.1 典型误区

问题类型错误表现解决方案
装饰顺序错误功能叠加顺序不对影响结果出错使用建造者模式来管理装饰顺序
内存泄漏未正确的释放装饰链对象采用智能指针(如unique_ptr)来管理资源
过度装饰装饰层级过多导致性能下降限制装饰层数或使用缓存机制

5.2 性能优化策略

  • 对象池技术:复用频繁创建的装饰器对象;
  • 延迟初始化:仅在需要时创建装饰器;
  • 装饰器合并:将多个常组合的装饰器合并为复合装饰器;

六、总结与模式对比

6.1 核心优势

  • 灵活扩展:运行时动态增减功能(如游戏道具在取用时实时生效);
  • 代码复用:装饰器可跨多个组件使用(如边框装饰器适用于按钮/输入框);
  • 符合SOLID原则:单一职责(每个装饰器只做一件事),以及开闭原则;

6.2 模式对比

模式使用目的实现方式
装饰模式能够动态的添加职责组合 + 继承
策略模式方便进行算法替换接口 + 实现类
适配器模式主要为了接口转换包装旧接口
桥接模式分离抽象与实现的耦合分层抽象

6.3 适用性建议

推荐使用场景

  • 需要动态扩展对象功能的系统;
  • 无法通过继承实现的功能组合;
  • 需要撤销临时功能的场景;

不适用场景

  • 功能固定的简单对象不用使用装饰模式;
  • 装饰模式会导致对象接口膨胀,接口比较多的不太合适;

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

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

相关文章

【JavaScript 简明入门教程】为了Screeps服务的纯JS入门教程

0 前言 0-1 Screeps: World 众所不周知&#xff0c;​Screeps: World是一款面向编程爱好者的开源大型多人在线即时战略&#xff08;MMORTS&#xff09;沙盒游戏&#xff0c;其核心机制是通过编写JavaScript代码来控制游戏中的单位&#xff08;称为“Creep”&#xff09;&#…

LabVIEW远程控制通讯接口

abVIEW提供了多种远程控制与通讯接口&#xff0c;适用于不同场景下的设备交互、数据传输和系统集成。这些接口涵盖从基础的网络协议&#xff08;如TCP/IP、UDP&#xff09;到专用技术&#xff08;如DataSocket、远程面板&#xff09;&#xff0c;以及工业标准协议&#xff08;如…

LeetCode hot 100—寻找重复数

题目 给定一个包含 n 1 个整数的数组 nums &#xff0c;其数字都在 [1, n] 范围内&#xff08;包括 1 和 n&#xff09;&#xff0c;可知至少存在一个重复的整数。 假设 nums 只有 一个重复的整数 &#xff0c;返回 这个重复的数 。 你设计的解决方案必须 不修改 数组 nums…

31天Python入门——第15天:日志记录

你好&#xff0c;我是安然无虞。 文章目录 日志记录python的日志记录模块创建日志处理程序并配置输出格式将日志内容输出到控制台将日志写入到文件 logging更简单的一种使用方式 日志记录 日志记录是一种重要的应用程序开发和维护技术, 它用于记录应用程序运行时的关键信息和…

AI Agent开发大全第八课-Stable Diffusion 3的本地安装全步骤

前言 就像我们前面几课所述,本系列是一门体系化的教学,它不像网上很多个别存在的单篇博客走“吃快餐”模式,而是从扎实的基础来带领大家一步步迈向AI开发高手。所以我们的AI课程设置是相当全面的,除了有牢固的基础知识外还有外面互联网上也搜不到的生产级实战。 前面讲过…

用selenium+ChromeDriver豆瓣电影 肖申克的救赎 短评爬取(pycharm 爬虫)

一、豆瓣电影 肖申克的救赎 短评urlhttps://movie.douban.com/subject/1292052/comments 二、基本知识点讲解 1. Selenium 的基本使用 Selenium 是一个用于自动化浏览器操作的库&#xff0c;常用于网页测试和爬虫。代码中使用了以下 Selenium 的核心功能&#xff1a; webdriv…

JavaScrip-模版字符串的详解

1.模版字符串的详解 1.1 模版字符串的使用方法 在ES6之前&#xff0c;如果我们想要将字符串和一些动态的变量&#xff08;标识符&#xff09;拼接到一起&#xff0c;是非常丑陋的&#xff08;ugly) ES6允许我们使用模版字符串来嵌入变量或者表达式来进行拼接 首先&#xff0c;…

海康设备http监听接收报警事件数据

http监听接收报警事件数据 海康获取设备报警事件数据两种方式&#xff1a; 1、sdk 布防监听报警事件数据&#xff08;前面文章有示例&#xff09; 2、http监听接收报警事件数据 http监听接收报警事件数据&#xff0c;服务端可以使用netty通过端口来监听获取事件数据。 WEB 端…

【STM32】编写程序控制开发板的RGB LED灯

目录 1、原理图2、文件结构3、使用寄存器模式点亮3.1、什么是寄存器3.2、寄存器开发的本质3.3、寄存器开发步骤3.4、主要源码3.4.1、main.c3.4.2、drv_gpio.h3.4.3、drv_gpio.c3.4.4、使用BSRR和BRR影子寄存器优化drv_gpio.c3.4.5、效果演示 4、使用标准库模式点亮4.1、使用标准…

MyBatis-Plus 的加载及初始化

在 Spring Boot 启动过程中&#xff0c;MyBatis-Plus 的加载和初始化涉及多个阶段的工作。这些工作包括 MyBatis-Plus 自身的配置解析、Mapper 接口的扫描与注册、SQL 语句的动态注入以及底层 MyBatis 的初始化等。以下是对整个过程的详细分析&#xff1a; 1. Spring Boot 启动…

关于解决Ubuntu终端及系统字体大小的问题

在Ubuntu中调整终端和系统字体大小可以通过以下方法&#xff08;可能不仅仅只是这几种&#xff09;实现&#xff1a; 1. 调整系统字体大小 打开终端并输入以下命令&#xff0c;安装GNOME Tweaks&#xff0c;等待安装完成&#xff1a; sudo apt install gnome-tweaks 接着进行…

Rust vs. Go: 性能测试(2025)

本内容是对知名性能评测博主 Anton Putra Rust vs. Go (Golang): Performance 2025 内容的翻译与整理, 有适当删减, 相关数据和结论以原作结论为准。 再次对比 Rust 和 Go&#xff0c;但这次我们使用的是最具性能优势的 HTTP 服务器库---Hyper&#xff0c;它基于 Tokio 异步运…

【NLP 48、大语言模型的神秘力量 —— ICL:in context learning】

目录 一、ICL的优势 1.传统做法 2.ICL做法 二、ICL的发展 三、ICL成因的两种看法 1.meta learning 2.Bayesian Inference 四、ICL要点 ① 语言模型的规模 ② 提示词prompt中提供的examples数量和顺序 ③ 提示词prompt的形式&#xff08;format&#xff09; 五、fine-tune VS I…

P1722 矩阵Ⅱ - 洛谷

题源&#xff1a;P1722 矩阵 II - 洛谷 看了题目之后&#xff0c;需要注意的是&#xff1a; ①在1 ~ i 个格子中红色数量 > 黑色数量 ②最后&#xff0c;在2 * n 个格子中&#xff0c;红色数量 黑色数量 根据这两个约束条件&#xff0c;可以知道&#xff0c;第一个格…

行业白皮书2025 | 益企研究院:AI时代的存储基石

在当今科技飞速发展的时代&#xff0c;AI技术已成为推动各行业变革的关键力量。日前&#xff0c;益企研究院重磅发布《AI时代的存储基石》白皮书。 下载方式&#xff1a;关注“渡江客涂鸦板”&#xff0c;回复st250326获取免费下载地址 数据需求与技术挑战&#xff1a; AI技术…

vue 封装 Axios菜鸟教程

1、Axios依赖下载 $ npm install axios 2、以下链接为Axios 的api Axios 实例 | Axios中文文档 | Axios中文网 3、 项目新建request.js&#xff0c;文件名称按照驼峰命名法就可以 4、封装request.js代码如下 import axios from "axios"//创建axios实例&#xff0…

[项目]基于FreeRTOS的STM32四轴飞行器: 十一.MPU6050配置与读取

基于FreeRTOS的STM32四轴飞行器: 十一.MPU6050 一.芯片介绍二.配置I2C三.编写驱动四.读取任务的测试五.MPU6050六轴数据的校准 一.芯片介绍 芯片应该放置在PCB中间&#xff0c;X Y轴原点&#xff0c;敏感度131表示范围越小越灵敏。理想状态放置在地面上X&#xff0c;Y&#xf…

iOS常见网络框架

URLSession、Alamofire 和 Moya 1. URLSession 1.1 核心概念 URLSession 是 Apple 官方提供的网络请求 API&#xff0c;封装在 Foundation 框架中。它支持 HTTP、HTTPS、FTP 等协议&#xff0c;可用于&#xff1a; ​ • 普通网络请求&#xff08;GET/POST&#xff09; ​ …

AOA(到达角度)与TOA(到达时间)两个技术的混合定位,MATLAB例程,自适应基站数量,三维空间下的运动轨迹,滤波使用UKF(无迹卡尔曼滤波)

本文介绍一个MATLAB代码,实现了三维动态目标非线性定位与滤波系统,通过融合 到达角(AOA) 和 到达时间(TOA) 的混合定位方法,结合 无迹卡尔曼滤波(UKF) 处理非线性观测模型,优化轨迹精度。代码支持自适应基站数量配置,适用于复杂非线性场景的定位研究。 文章目录 运行…

Ubuntu 重置密码方法

目录 修改过 root 密码&#xff0c;重置密码的方法没改过 root 密码‌&#xff0c;重置密码的方法 修改过 root 密码&#xff0c;重置密码的方法 Ubuntu 默认禁用root用户&#xff0c;意思就是安装好Ubuntu系统后&#xff0c;root用户默认是没有密码的&#xff0c;普通用户通过…