面向对象技术简述(含设计模式)

news2024/11/26 4:54:54
6.9.2 面向对象技术
  • 面向对象 = 对象 + 分类 + 继承 + 通过消息的通信 面向对象 = 对象 + 分类 + 继承 + 通过消息的通信 面向对象=对象+分类+继承+通过消息的通信
  • 其中包括:
    1. 对象
      • 运行的实体;
      • 既包含属性/数据,又包含方法/行为/操作数据的函数
      • 与其说是对象,不如说是程序模板
      • 一个对象由:对象名、属性(数据)、操作(方法)组成;
    2. 消息
      • 对象间进行通信的一种构造代表着一组包含特定格式的信息);
      • 对象 1 → 消息 对象 2 对象1\overset{\text{消息}}\rightarrow 对象2 对象1消息对象2,对象2对消息进行解释并予以响应,这称为消息传递
      • 发送对象的对象不需要知道接收对象如何对请求予以相应
      • 定义了一组大体上相似的对象;
      • 类是在对象之上的抽象,对象是类的具体化,是类的实例
    3. 继承
      • 父类和子类之间共享数据和方法的机制
      • 一个父类可以有多个子类,但一个子类只能继承自一个父类
    4. 多态
      • 不同对象接收到同一消息后产生不同结果,这一现象被称为多态;
      • 泛化 = 多态 , 实现 = 继承
      • 简单来说是同一操作作用于不同的对象,会有不同的解释
6.9.2.1 设计原则
  1. 单一职责原则
    • 要设计目的单一的类;
  2. 开放-封闭原则
    • 对扩展开放,对修改关闭股权警告);
  3. 里氏替换原则Liskov substitution principle
    • 子类可以替换父类
  4. 依赖倒置原则
    • 针对接口编程,而不是针对实现编程
    • 要依赖于抽象,而不是具体实现;
  5. 接口隔离原则
    • 宁愿使用多个专门的接口也比使用单一的总接口要好
  6. 组合复用原则
    • 要尽量少用继承,要尽量使用组合

    Q:什么是组合,为什么是组合?
    A:组合就是在一个对象中嵌套另一个对象作为对象成员来使用。组合非常有利于代码的复用,且关系可以动态变化,一个对象中可以包含多个不同的子对象,从而实现更为复杂的组合变化。更重要的是继承使用的太多的话,对象间的耦合程度过高,代码会变得臃肿混乱,容易一处修改就使得代码陷入bug和混乱

  7. 迪米特原则Demeter Principle
    • 一个对象应当对其他对象尽可能少的“了解”;
    • 也就是,不同函数之间应避免直接访问到彼此的内部信息,需要使用的时候直接调用就好了;
6.9.2.2 设计模式的概念和分类
  • 只关注软件系统的设计,与具体的实现语言无关(软考可选择c++或者java);

  • 设计模式一般会有4个要素:

    1. 模式名称;
    2. 问题;
    3. 解决方案;
    4. 效果;
  • 设计模式的分类(23种):
    在这里插入图片描述

    • 常考的有: 工厂方法、抽象工厂、构建器、适配器、装饰、命令、中介者、观察者 工厂方法、抽象工厂、构建器、适配器、装饰、命令、中介者、观察者 工厂方法、抽象工厂、构建器、适配器、装饰、命令、中介者、观察者
    1. 创建型模式
      • 抽象了实例化过程;
      • 关注对象的创建过程,将对象的创建与使用分离,提供了了一个灵活的方式来创建对象,而无需指定具体的类;
    2. 结构型模式(常考选择题
      • 描述如何组合类和对象以获得更大的结构;
      • 采用继承机制来组合接口或者实现
    3. 行为型模式
      • 不仅描述对象或类的模式,还描述它们之间的通信模式;
      • 关注对象之间的交互和职责分配、对象之间的交互方式;
        1. 行为类模式使用继承机制在类间分派行为;
        1. 行为对象模式使用对象复合
      • 为什么要使用行为型模式:
        1. 提高代码复用性: 通过封装变化的部分,减少重复代码;
        2. 增强代码可维护性: 将复杂的逻辑拆分成更小的、可管理的单元
6.9.2.2.1 工厂方法模式(factory_method
  • 在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型,本质是将子类的实例化给推迟了;
  • 它建议使用特殊的工厂方法代替对于对象构造函数的直接调用如:new),直接调用改在工厂方法中进行。这允许你在子类中重写工厂方法, 从而改变其创建产品的类型

    仅当这些产品具有共同的基类或者接口时, 子类才能返回不同类型的产品, 同时基类中的工厂方法还应将其返回类型声明为这一共有接口;

  • 【要素】:共同接口的创建方法,子类方法多态;
  • 举例:
  • 模式结构:
    在这里插入图片描述

在这里插入图片描述

6.9.2.2.2 抽象工厂模式(abstract factory
  • 是在工厂方法基础上的升级,应对的是某一类对象下的所有子类,而不是某一个子类(某一个子类是工厂方法);
  • 例如对于椅子、沙发、餐桌等家具来说,按照设计风格的不同可以分为中式、日式、维多利亚式、北欧式。现在我们想生产一些家具,但是要求每一批生产的都是一种生产风格。此时,就可以声明抽象工厂(一个包含了批次中所有产品构造方法的接口),如 F u r n i t u r e F a c t o r y { + c r e a t e C h a i r ( ) , + c r e a t e S o f a ( ) , + c r e a t e T a b l e ( ) } FurnitureFactory\{+createChair(), +createSofa(), +createTable()\} FurnitureFactory{+createChair(),+createSofa(),+createTable()},这些方法必须返回抽象的产品类(即Chair、Sofa、Table)。在这以后,应对不同设计风格的生产要求,可以通过接口创建特定类型的“工厂”对象,在这些“工厂”对象中对构造方法进行重写,如由FurnitureFactory创建ChineseFurnitureFactory来生产ChineseChairChineseSofaChineseTable
  • 模式的结构:
    在这里插入图片描述
6.9.2.2.3 构造器模式/生成器模式(builder
  • 允许你使用相同的创建代码分步骤创建不同类型和形式的复杂对象;

  • 生成器模式建议将对象构造代码从产品类中抽取出来, 并将其放在一个名为生成器的独立对象中。生成器能够让你能够分步骤创建复杂对象。 生成器不允许其他对象访问正在创建中的产品;

  • 例如你要建造一间房子,需要建造墙壁、房门、管道、地板、天花板。这时候你有三种思路:

    1. 第一种是创建一个房子的基类(BaseEntity)储存一定的参数,并在其基础上进行实现或者泛化。但如果后来者要对房子添加一些基类中没有出现过的修改,出现了基类中没有的参数,构造函数也要变动,则需要修改基类,这样会使开发非常复杂;
    2. 第二类是在基类中创建一个涵盖所有参数的超级构造函数,但这样会造成严重的资源浪费。大多数情况下,超级构造函数的参数都没有用,故调用起来非常复杂;
    3. 最后一种也就是额外创建一个构造器,将对象的构造过程拆分成一组“步骤”,如buildWall()创建墙壁buildDoor()创建房门buildTube()创建管道等。每次创建对象,只需要通过构造器对象选择性地调用特定的对象执行,按顺序一次性完成相应步骤即可。当创建不同形式的产品时,一些构造步骤可能需要不同的实现(参数不同),则需要对应创建不同产品的构造器(如Builder1Builder2);
  • 模式的结构:在这里插入图片描述

    在有需要的情况下,可以进一步将用于创建产品的一系列生成器步骤调用抽取成为单独的主管类(Director主管类可定义创建步骤的执行顺序, 而生成器则提供这些步骤的实现,或者说主管类构造了使用生成器接口的对象。事实上,对于客户端代码来说, 主管类完全隐藏了产品构造细节。 客户端只需要将一个生成器与主管类关联, 然后使用主管类来构造产品, 就能从生成器处获得构造结果了;

6.9.2.2.4 原型模式(Prototype
  • 针对不想复制品依赖类或者只知道要复制对象的部分接口不知道全貌的情况(即:从外部复制对象并非总是可行);
  • 原型模式将克隆过程委派给被克隆的实际对象。 模式为所有支持克隆的对象声明了一个通用接口, 该接口让你能够克隆对象, 同时又无需将代码和对象所属类耦合。 通常情况下, 这样的接口中仅包含一个克隆方法。克隆方法会创建一个当前类的对象, 然后将原始对象所有的成员变量值复制到新建的类中你甚至可以复制私有成员变量, 因为绝大部分编程语言都允许对象访问其同类对象的私有成员变量);
  • 支持克隆的对象即为原型。 当你的对象有几十个成员变量和几百种类型时, 对其进行克隆甚至可以代替子类的构造(方法是:创建一系列不同类型的对象并不同的方式对其进行配置。 如果所需对象与预先配置的对象相同, 那么你只需克隆原型即可, 无需新建一个对象);

事实上,这类复制与其说是克隆,不如说是有丝分裂,所有“遗传物质”(属性、方法)都和原型一摸一样;

  • 其模式结构是:在这里插入图片描述
6.9.2.2.5 单例模式(Singleton)(问题非常多
  • 确保【1】一个类只有一个实例, 并【2】提供一个访问该实例的全局节点。但这违反了单一职责原则

    实际上,只解决了上文描述中的其中一个的东西,都被称为单例。单例在现在非常常用;

  • 实现方法:
    1. 在类中添加一个私有静态成员变量用于保存单例实例;
    2. 创建静态方法,在首次被调用时创建一个新对象, 并将其存储在静态成员变量中。 此后该方法每次被调用时都返回该实例延迟初始化);
    3. 将类的构造函数设为私有只有一个实例)。 类的静态方法仍能调用构造函数, 但是其他对象不能调用;
    4. 检查客户端代码, 将对单例的构造函数的调用替换为对其静态方法的调用;
6.9.2.2.6 适配器模式(Adapter
  • 类似于……
    在这里插入图片描述

  • 适配器是一个特殊的对象, 能够转换对象接口, 使其能与其他对象进行交互(调整格式、属性等);

  • 模式通过封装对象将复杂的转换过程隐藏于幕后,被封装的对象甚至察觉不到适配器的存在;

  • 例如: 在这里插入图片描述

  • 模式的结构是:

    在这里插入图片描述在这里插入图片描述

6.9.2.2.7 责任链模式(Chain of Responsibility
  • 允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者;
  • 详细内容见于此处;
6.9.2.2.8 命令模式(Command

优秀的软件设计通常会将关注点进行分离, 而这往往会导致软件的分层(网络层、Mybatis_plus后端);

  • 将请求封装为一个对象,从而可用不同的请求对客户进行参数化,同时将请求排队或者记录请求日志,支持可撤销的操作;
  • 一个 GUI 对象传递一些参数来调用一个业务逻辑对象, 这个过程通常被描述为一个对象发送请求给另一个对象。命令模式建议 GUI 对象不直接提交这些请求。 你应该将请求的所有细节 (例如调用的对象、 方法名称和参数列表) 抽取出来组成命令类, 该类中仅包含一个用于触发请求的方法命令对象负责连接不同的 GUI 和业务逻辑对象类似于视图和数据库)。 此后, GUI 对象无需了解业务逻辑对象是否获得了请求, 也无需了解其对请求进行处理的方式。 只需要GUI对象触发命令即可, 命令对象会自行处理所有细节工作。;
  • 让所有命令实现相同的接口。 该接口通常只有一个没有任何参数的执行方法, 让你能在不和具体命令类耦合的情况下使用同一请求发送者执行不同命令;

    有一个问题,由于接口的方法不含有任何参数,当需要接受请求的参数时,需要另寻他招:使用数据对命令进行预先配置, 或者让其能够自行获取数据用属性或者对象接收并调用而不是传参);

  • 其模式类似于:在这里插入图片描述
6.9.2.2.9 观察者模式(Observer
  • 定义对象间的一种一对多的依赖关系当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新
6.9.2.2.10 状态模式(State
  • 状态变成类
  • 允许一个对象在其内部状态改变时改变它的行为
6.9.2.2.11 策略模式(Strategy
  • 最常见的就是:定义一系列的算法,把它们一个个封装起来,并且使他们可以相互替换。此时算法独立于使用它的用户而变化;
  • 本质还是【多方案切换】这一套;

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

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

相关文章

【信号处理】基于联合图像表示的深度学习卷积神经网络

Combined Signal Representations for Modulation Classification Using Deep Learning: Ambiguity Function, Constellation Diagram, and Eye Diagram 信号表示 Ambiguity Function(AF) 模糊函数描述了信号的两个维度(dimensions):延迟(delay)和多普勒(Doppler)。 …

【C++练习】两个实型数的加法运算

题目: 编写一个C程序,实现两个实型数的加法运算并输出结果。 要求: 定义一个函数 dadd,该函数接收两个 double 类型的参数,并返回它们的和。在 main 函数中,提示用户输入两个实型数(double 类…

【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)

博主说明:本文项目编号 T 061 ,文末自助获取源码 \color{red}{T061,文末自助获取源码} T061,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…

Sql面试题二:请查询出用户连续三天登录的所有数据记录

问题: 现有用户登录记录表,请查询出用户连续三天登录的所有数据记录 id dt 1 2024-04-25 1 2024-04-26 1 2024-04-27 1 2024-04-28 1 2024-04-30 1 2024-05-01 1 2024-05-02 1 2024-05-04 1 2024-05-05 2 2…

科研绘图系列:R语言分组堆积图(grouped stacked barplot)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包准备画图主题数据链接导入数据画图数据准备图例图1图2合并图系统信息介绍 分组堆积图(Grouped Stacked Bar Chart)是一种数据可视化图表,它结合了分组柱状图和堆积柱状图…

世界技能竞赛大数据应用开发环境1:1还原

集群情况 模块A搭建环境,在容器中搭建大数据平台 Pc机,安装安装比赛需要软件 模块B中使用idea快速开发完成数据处理 模块E包含了接口数据,使用vs code快速搭建vue数据可视化

【网络协议大花园】应用层 http协议的使用小技巧,用好了都不用加班,效率翻两倍(下篇)

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. 🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人…

SpringBoot源码解析(一)

SpringBoot自动装配原理 SpringBootApplication注解 我们在使用SpringBoot时,通常使用的是SpringBootApplication这个注解,比如: 而这个注解的定义为下图,可以发现这个注解上有另外三个注解:SpringBootConfiguration…

流类库与输入输出

来源:《C语言程序设计》 像C语言一样,C语言也没有输入输出语句。 但C标准库中有一个面向对象的输入输出软件包,即I/O流类库。 流是I/O流类的中心概念。 ------ I/O流类库是C语言中I/O函数在面向对象的程序设计方法中的一个替换产品。 -…

k8s图形化显示(KRM)

在master节点 kubectl get po -n kube-system 这个命令会列出 kube-system 命名空间中的所有 Pod 的状态和相关信息,比如名称、状态、重启次数等。 systemctl status kubelet #查看kubelet状态 yum install git #下载git命令 git clone https://gitee.com/duk…

理解鸿蒙app 开发中的 context

是什么 Context是应用中对象的上下文,其提供了应用的一些基础信息,例如resourceManager(资源管理)、applicationInfo(当前应用信息)、dir(应用文件路径)、area(文件分区…

ML1:sklearn env

sklearn: 中文参考: https://scikit-learn.cn/stable/modules/linear_model.html#ordinary-least-squares https://scikit-learn.org.cn/view/4.html ——》为主,不懂地方参考上面中文以及下面英文 英文参考: https://scikit…

五分钟入门双拼!

‍这是从零开始学双拼的第一篇:概述 双拼的原理 如果你使用全拼,想要完整敲出一个字的读音,需要敲出这个字拼音的每个字母。 虽然简拼能简化一点步骤,但除非是很常见的成语、俗语,否则重码率很高,选词很…

基于STM32的智能充电桩:集成RTOS、MQTT与SQLite的先进管理系统设计思路

一、项目概述 随着电动车的普及,充电桩作为关键基础设施,其智能化、网络化管理显得尤为重要。本项目旨在基于STM32微控制器开发一款智能充电桩,能够实现高效的充电监控与管理。项目通过物联网技术,提供实时数据监测、远程管理、用…

毕业后如何查找获取文献

当我们毕业后就无法再使用自己学校的数据库资源了,如果需要查找文献该从哪里获取资源呢?下面这个方法很简单而且有效: 一、首先选对科研工具 文献党下载器,把大量数据库资源整合在一起,直接去文献来源数据库查找获取…

串口接收,不定长数据接收

###1.CUBE-MX配置串口 2.我采用串口中断接收,打开中断接口 3.时钟同样8倍频,1分频,使用内部时钟 打开串口中断 main() { __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); // 启用空闲中断__HAL_UART_ENABLE_IT(&huart1, UART_IT_R…

2024 高质量 Java 面试题集锦:高级 Java 工程师面试八股汇总

最近感慨面试难的人越来越多了,一方面是市场环境,更重要的一方面是企业对 Java 的人才要求越来越高了。 基本上这样感慨的分为两类人,第一,虽然挂着 3、5 年经验,但肚子里货少,也没啥拿得出手的项目&#x…

express 使用JWT认证

1、JWT的理解 JWT 的组成部分: 分别是 Header(头部)、Payload(有效荷载)、Signature(签名) 三者之间使用英文的"."分隔, Pyload 部分才是真正的用户信息,他是用户信息经过加密之后生成的字符串 Header 和 Signature 是 安全性相关的部分,只是为了保证 Tok…

linux将mysql加到systemctl命令中

linux中,想将mysql加到systemctl命令中,首先需要确定mysql的安装位置 在/etc/systemd/system目录下新建mysql.service vim /etc/systemd/system/mysql.service 复制如下内容:确保你自己的mysql路径是否正确 [Unit] DescriptionMySQL Server…

【Mac】安装 VMware Fusion Pro

VMware Fusion Pro 软件已经正式免费提供给个人用户使用! 1、下载 【官网】 下拉找到 VMware Fusion Pro Download 登陆账号 如果没有账号,点击右上角 LOGIN ,选择 REGISTER 注册信息除了邮箱外可随意填写 登陆时,Username为…