百度俱乐部(public@hustbaidu.com)面向对象讲座---封装变化的事物 by Kai.Zhang

从零到一:RT-Thread与W5500的硬件抽象层设计哲学与实践启示 本文深入探讨了RT-Thread操作系统下W5500以太网模块的硬件抽象层(HAL)设计哲学与实践。通过GD32F103和STM32F103平台的适配案例,详细阐述了如何利用RT-Thread的驱动框架实现跨平台硬件无关性、模块化设计及配置定制,为嵌入式开发者提供了可复用的HAL设计方法论和实战经验。 阅读详情

序言

人们使用面向对象设计有两个很重要的原因,一个是从现实的角度去考虑问题而不是机器的角度,这使开发变得更快更敏捷。第二个原因便是为了可扩展编程与代码复用,使得在软件开发过程的重复劳动更少。本次讲座要讲的就是如何利用“封装变化的事物”这一思想来进行面向对象的设计,达到代码复用和可扩展编程的目的。

注:此讲座需要大家提前掌握面向对象的一些概念:类,对象,继承,封装(之前YGui的面向对象讲座中讲述)

为何要封装变化的事物

在这个世界,万事万物都是不一样的,我们在编写程序的时候面对的问题也都各不一样,一般情况下面对不同的问题我们会有不同的解决方法,这样的设计方法可以使我们的程序设计高度针对我们所要解决的问题,使得代码执行起来很高效。但是,当我们有大量的问题需要解决的时候,这样的设计方法可能会导致大量的工作甚至是大量的重复劳动,此时我们希望能将以前的解决方案与代码能最大程度的用到新的问题上来减少我们的劳动。其次,即使我们已经解决得很好的问题也有可能随着时间的推移,要求做出一些改变或者增加一些功能来适应新的情况,此时,我们希望最大程度不改变原有代码的结构,同时能应付新的变化。在这种情况,我们的一个解决方法就是把那些变化的事物都封装起来,使得从外部看他们都是一样的,这样我们就可以从容面对各种变化的事物以及问题了。而这种思想,在程序设计中是通过面向对象的技术来实现的。

如何封装

我们会通过几个例子来逐步了解如何来封装变化的事物。

首先假设我们在写一个游戏,在这个游戏中我们会想玩家提供数种不同的交通工具,例如:轿车、卡车、大巴甚至是坦克。他们都是不同的交通工具,也就是变化的物,而我们希望在程序代码中不需要对不同交通工具写不同的代码来控制他们(起码对于基本的一些操作,如前进、后退是这样),取而代之的是统一的方法,例如:

vehicle.moveFoward();
这时我们使用接口来达到这个目的,把不同交通工具动作的具体实现代码封装在接口之内:

interface vehicle {

       void moveFoward();

       void moveBack();

}

class moto implements vehicle {

       void moveFoward() { this.x += 1; }

       void moveBack() { this.x -= 1; }

}

 

class tank implements vehicle {

       void moveFoward() { this.x += 0.2; }

       void moveBack()  { this.x -= 0.2; }

}

通过这样的方式,我们可以对任意多不同的交通工具编写不同的行动代码,而在使用这些交通工具的地方,代码可以统一为vehicle.moveFoward();这样就使得这个游戏的扩展性得到了提升。

当然,我们可能需要用到一些特殊的交通工具的独有的能力,比如说坦克的开炮,面向对象的运行时类型识别可以帮助我们很容易的实现这一点,在这个地方我们先不讲。

 

我们再来看一个复杂点的例子。

比如我们在编写一个文本处理软件(就像WORD那样),那么给用户提供后悔药是一件很重要的事。通过“撤销”功能,用户可以将失误的操作取消,使文本恢复原来的样子。

很显然我们需要记录用户的操作并将它们按先后次序排好,使得用户可以一个一个的撤销它们。问题是,当用户点击“撤销”按钮时,我们读出用户最后的操作,然后呢?

当然,我们可以判断出用户做了什么类型的操作,改动了哪些地方,然后把改动的地方都恢复。但是,当我们给用户提供越多的可选操作的时候我们也就需要在“撤销”的method里面去判断越多种不同的情况,并且写大量的代码来针对不同的操作做不同的恢复。

这并不是真正的大问题,问题是,当我们发布这个软件后,我们希望对她进行升级,给用户提供更多的功能,我们不得不重新修改“撤销”的method,编写新的代码来支持新的恢复。

我们选择封装这些变化的事情来解决这个问题。

无论用户做了什么样的操作,从删除一个字符到插入了一张图片,我们到把这些变化的事封装起来使得从外部看起来用户就是执行了一个操作,那么当用户点击“撤销”时,无论是执行了恢复被删除的字符还是取消了插入图片,我们也把他们都封装起来使得外面看来用户就是撤销了一个命令而已。由于不同的命令有着具体不同的撤销方法,我们命令的执行和撤销都交给该具体的对象自己处理,而用户执行某个操作时,只是通知那个对象去执行,撤销是通知那个对象去撤销。(这其实就是命令设计模式,关于设计模式以后我们会详细讲到)

interface Command {

       void execute();

       void undo();

}

 

class DeleteChar implements Command {

       void execute() {/*save the information about the selected char then delete it*/}

       void undo() {/*use the saved information to get-back the deleted char*/}

}

 

class InsertPic implements Command {

       void execute() {/*insert the picture save the information about it*/}

       void undo(/*delete the inserted picture*/)

}

这样,无论以后我们为用户提供什么样的操作,在撤销的method里面,我们只需要读出用户最后执行的命令,然后执行其undo方法。

Command lastCommand = getLastCommand();

lastCommand.undo();

即可。

 

到目前为止,我们使用面向对象的思想来设计进行得很顺利,可是有时候我们会遇到有些复杂的问题我们暂时无法解决,或者解决问题的代码很简单但是很繁琐。这时我们希望使用别人编写好的代码,不幸的很可能对方的设计并没有考虑到我们的软件系统,我们无法直接使用他们已经编写好的类,此时修改我们的整个软件系统去适应他们编写好的类显然也是不现实的,这时候封装变化的事物这一思想再一次发挥了他的作用。

别人的代码能解决我们的问题我们却不能直接使用往往是因为一些小的原因,例如参数要求不用(比如我们需要一个画圆的方法以圆心坐标和半径长度为参数画出一个圆,而别人写好的画圆的方法却是以圆的外接正方形的左上角坐标和直径长度为参数来画圆的,你或许怀疑这样的画圆方法的存在,然而windows GDI正是使用这样的参数画圆),或者是他的某一个方法不能直接完成你所要求的功能,需要将他写的若干method组合起来使用,或者仅仅是因为他的类不是由你所要求的某个子类继承的,此时我们将其他所有人写的类封装起来,使他们看起来和我们自己写的类是一样的。

例如,我们现在拿到了一个可以以圆的外接正方形的左上角坐标和直径长度为参数来画圆的类:

class SomeonesCircle {

    draw(int x, int y, int length) {/*draw the circle*/}

}

现在我们来封装他

class Mycircle {

public:

    draw(int x, int y, int radius) { circle.draw(x-radius, y-radius, radius*2); }

private:

    SomeonesCircle circle;

}

这样别人写好的类就可以为我们的系统工作了,即使我们的circle是由我们的某个根类,例如:MyShape继承而来,也完全没有问题。

 

至此我们所接触的例子只是面向对象的设计中的冰山一角,同时我要再次声明:面向对象并不只是为了复用代码和可扩展性编程而出现的。希望大家在以后的学习中多从别人的代码和设计中去学习如何使用面向对象的思想去设计,同时去开发自己的面向对象的设计。

Scratch 3.0角色控制避坑指南:为什么你的键盘移动总卡顿? 本文深入剖析了Scratch 3.0中角色移动卡顿的根本原因,指出依赖`当按下`事件积木的局限性。通过对比分析,推荐采用`重复执行`结合`如果<键被按下?>`的循环控制方案,并引入速度变量模拟惯性,从而实现流畅、实时的键盘控制优化,显著提升游戏操作体验。 阅读详情

相关推荐

软考 系统架构设计师历年真题集萃(332)—— 2026年5月系统架构设计师真题25

软考 系统架构设计师历年真题集萃(332)—— 2026年5月系统架构设计师真题25

phmatthaus的专栏 39

百度PC排名-BD_PC排名-百度电脑端排名-百度PC端搜索排名API接口介绍

戳这里查看详情。

聚美智数 271

AI人工智能基础学习与面试笔试资料合集.zip

AI人工智能基础学习与面试笔试资料合集.zip

百度PC排名-PC排名-百度PC排名API接口介绍

名称类型必须说明domainString是查询的域名catalogString否目录名称(默认选择全部数据)pageint否分页(默认第1页,可自行选择页码,每页最多100条数据)戳这里查看详情。

聚美智数 252

百度PC网站权值-百度PC端SEO权重-百度搜索PC权重-百度PC自然搜索权重API接口介绍

戳这里查看详情。

聚美智数 262

从“搜索公司”到“全栈AI第一股”:百度的估值故事正在重写

昆仑芯做芯片,智能云做算力,文心大模型做模型,百度搭子做应用,萝卜快跑做出行——每一块业务都在指向同一个方向:百度已经是一家“全栈AI公司”了。双重主要上市的意义,正在于此——它不是为百度找钱,而是为百度找“对的定价方式”。资本市场用真金白银投票,但真正值得关注的不是股价的短期波动,而是这件事背后的长期逻辑:百度的业务早已不是一家“搜索公司”,但市场还在用“搜索公司”的标尺丈量它。港股通大门打开后,更懂中国AI产业链的内地资金将推动市场从“搜索公司”的PE估值切换到“全栈AI公司”的SOTP分部估值。

xiongmosy的博客 252

从绿萝到AI搜索:我给百度算法写了份26年编年史

名字一个比一个狠:绿萝、石榴、冰桶、白杨、天网、蓝天、烽火、飓风、清风、闪电、惊雷、极光、季风、细雨、信风、劲风……打买卖外链、刷点击。不是不打了,是打法变了——所有规则收编进《百度搜索算法规范详解》常态公示,惩罚从"新算法公告",变成"季度下架多少违规站点"的数据通报。所以我一直跟客户说:百度26年,算法从无到有、从有到多、又从多到"无"(并入AI模型),名字换来换,本质只干了一件事——把投机取巧的人清出,把认真做内容的人留下来。该问的是:我的内容,值不值得被一个比任何用户都挑剔的AI,推荐给用户。

2501_93625207的博客 310

2.4 大模型API密钥配置(OpenAI/阿里云/百度等)

注意:该方式仅在当前终端有效,若需永久生效,则需将命令添加到~/.bashrc(Linux)或~/.zshrc(macOS)文件中,执行命令source ~/.bashrc(或source ~/.zshrc)生效。右键“此电脑”→“属性”→“高级系统设置”→“环境变量”→“用户变量”→“新建”,变量名填写对应平台的密钥名称(如OPENAI_API_KEY),变量值填写API密钥,点击“确定”。(4)复制生成的API密钥(仅显示一次,务必保存好,丢失无法找回),建议存储在安全的地方(如密码管理器)。

夏天又到了的专栏 43

滴滴地图商用接入攻略:与高德 / 百度 / 腾讯横向对比

商用地图选型中,高德、百度、腾讯是多数企业的默认选择,但通用地图的成本高、垂直场景适配弱等问题,在出行、物流等行业日益凸显。滴滴地图(滴图开放平台)作为垂直场景服务商,凭借成本与场景优势逐渐普及。本文从技术、成本、功能、服务四个维度,横向对比四家服务商,为开发者与技术负责人提供选型攻略。

2601_96285505的博客 252

昆仑芯 XPU 怎么接入 Kubernetes 跑 DeepSeek-R1?CubeStudio 百度昆仑芯适配实操

CubeStudio 是一款国产化、云原生的一站式开源人工智能平台,同时覆盖传统机器学习、深度学习与大模型全链路(MLOps / MaaS / 算力调度 / 训推平台),开源协议 MIT,开源免费商用,开源版本已有数千家企业私有化部署。

210

百度 AI 搜索快速上手指南

<think>我们只需要根据用户要求生成摘要,不超过150字。用户提供了长篇文章,需要总结其核心内容。文章主要讲述如何接入智能搜索API,包括环境配置、密钥获取、代码实现、解析、排错和优化。摘要应简洁概括。</think>本文基于开发实践,讲解如何为智能应用接入搜索API以实现实时联网检索。内容涵盖环境搭建、密钥安全配置、核心代码实现、结果解析、常见报错处理及频率限制优化,帮助开发者从零完成首个搜索实例并稳定应用于生产环境。

日常笔记/总结/系列知识梳理 192

百度人脸离线SDK多平台部署报错排查指南:Android/Windows/Linux/国产系统/嵌入式ARM全记录

关于百度人脸SDK多平台部署报错排查。摘要需简洁概括核心:多平台部署常见报错、根因分析、解决方案。要控制字数。</think>百度人脸SDK多平台部署常见13类报错,覆盖Android、Windows、Linux、国产系统及嵌入式ARM。本文分析根因与解法:如so库缺失、GLIBC不匹配、授权失败、摄像头黑屏、NPU驱动问题等,并给出排查三步法,助开发者快速定位解决,少走弯路。

AI_CLOUD_disc的博客 516

设计模式精讲】3.统一建模语言(UML)速览

【摘要】:同一段设计,有人用两百条群消息仍说不清,有人用一张图五分钟达成共识。UML 的价值不是把系统画得复杂,而是选择合适视角,准确回答“有哪些角色”“谁依赖谁”“运行时谁先调用谁”“对象经历哪些状态”。本文以 Mermaid 为绘图工具,介绍类图、序列图、状态机图、用例图和活动图,重点讲透前三种。类图部分不再把不同关系硬排成一条强弱链,而是区分使用与整体关系、类型关系,并给出与 C++ 所有权和多态机制一致的代码;随后用订单事件和订单生命周期演示时序与状态表达,最后总结选图方法和常见误区。

码工许师傅 452

设计模式精讲】4.单例模式(Singleton)

【摘要】:全局配置、日志器、线程池,这类对象在整个进程里只需要一份。多数人的第一反应是定义一个全局变量,随后便陷入初始化顺序失控、重复构造、多线程竞争的泥潭。本文从全局变量的三宗罪讲起,给出单例模式的意图与结构;重点拆解 C++ 中线程安全单例的三种写法——Meyers’ Singleton、双检锁的坑与修正、std::call_once,并比较它们的行为差异。文章最后讨论单例的代价与替代方案,提醒读者:单例是受限的全局状态,能少用就少用。

码工许师傅 494

设计模式在 JS 中的应用:用 TS 重写经典模式,结合 React / Vue 真实业务场景

删除

2603_94941287的博客 244

【C++设计模式】工厂方法模式

工厂方法模式:提供一种通用的方法创建对象实例,把派生类对象的创建细节隐藏思路:调用一个专门的工厂函数,传入参数,由工厂函数负责生成对象。利用继承和多态实现这种模式用来解决:如果代码到处写new Plane(),new Boat(),当后续需要改动对象创建逻辑,就要修改项目中每一处new。优点缺点。

2401_88972077的博客 349

大白话说Java设计模式-42-访问者模式(业务实战篇)

本文结合大白商城3种营销对象×8种计算规则的业务痛点,详解访问者模式的核心设计思想与实战实现,对比硬编码互调、if-else堆叠、类爆炸等反面方案的缺陷,拆解元素接口、具体元素、访问者接口、具体访问者、对象结构五大核心角色,提供满减/折扣/立减3种访问者的生产级完整可运行代码与单元测试用例,对比访问者与策略、中介者模式的本质差异与适用场景,深入解读JDK Compiler API、ASM字节码、Spring SpEL的访问者设计思想,给出工程决策Checklist与6大常见坑解决方案,帮助开发者掌握如何运用

AI工程硬核派+电脑生活效率咖 291

设计模式精讲】7.建造者模式(Builder)

构造函数十个参数、其中七个可选,为了少写几个重载,你造出了一排「重叠构造函数」,调用处全是猜不透的 ("x", 0, false, nullptr, true)。本文从这个经典坏味道讲起,给出建造者模式:把复杂对象的 构造过程 从 表示 中分离,同一套步骤代码能攒出不同形态的产品。C++ 实现以 Refactoring Guru 的汽车/手册双生成器为例,覆盖传统写法与链式(Fluent)Builder、主管(Director)角色;进阶展示现代 C++ 的链式引用、std::optional 命名参数模拟

码工许师傅 189

【从提示链到多智能体协作:AI Agentic Design Patterns 深度解读】

先识别任务的不确定性、依赖关系、专业边界和风险,再选择刚好够用的控制流。提示链解决分解问题,ReAct 解决动态行动问题,Tool Use 解决能力连接问题,Planning 解决全局协调问题,Reflection 解决质量改进问题,多 Agent 解决专业化、并行化和权限边界问题,HITL 解决高风险决策问题。确定性工作流作为骨架单 Agent 处理不确定任务受控工具调用与最小权限必要的规划、反思和并行风险节点人工审批状态检查点、异常恢复和完整监控没有评估数据的 Agent 只是感觉良好;

youngerwang的博客 216

Agent 设计模式:五种经典模式全景,一次讲透

如果你写过代码,一定听过设计模式(Design Pattern)——单例、工厂、观察者、策略……它们不是「新技术」,而是**「前人踩了无数坑之后,总结出来的可复用的结构套路」**。比如「工厂模式」,解决的是「我不想在每个地方都new,想让创建对象的逻辑集中管理」这个问题。它没有新语法,只是一种组织代码的结构。Agent 设计模式,是同一套思想,搬到了「大模型应用」的领域。Agent 设计模式,就是「针对某一类任务,被反复验证有效的、组织大模型调用的结构方案」。它的核心不是「模型更强」,而是「

weixin_52201538的博客 424
上一篇: WPF-Windows Presentation Foundation简介
下一篇: [转贴]比较VC和Delphi
Dartagnan
博客等级 码龄17年 590粉丝 114原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值