当前位置: 首页 > news >正文

三、设计模式相关理论总结

一、面向对象编程

1.1 概述

简称Object Oriented Program(OOP),指以类或对象作为基础组织单元,遵循封装、继承、多态以及抽象等特性,进行编程。其中面向对象不一定遵循封装、继承、封装和多态等特性,只是前人总结的套路规范,遵循该套规范,可以快速,准确以及优雅的完成面向对象编程。

1.2 基本思想

软件系统设计的三个阶段:分析、设计以及实现。在面向对象领域,分别对应着面向对象分析(OOA)面向对象设计(OOD)以及面向对象编程(OOP)。OOA和OOD主要用于解决:被分为哪些类,类的属性和行为以及类与类之间的组织【交互关系】 等问题。整体来看:OOA -> 做什么OOD -> 怎么做OOP -> 将分析和设计翻译为代码的过程

1.3 四大特性详解

1.3.1 封装

本质上就是访问权限控制,哪些内容是允许访问的,哪些是不允许访问的,防止权限的滥用。存在的意义:

  • 保护数据不被随意滥用, 提高代码的可维护性
  • 通过暴露有限的行为, 提高代码的易用性

1.3.2 继承

对现实世界的直接映射,便于理解, 提高代码的复用性。但要注意继承的层级,层级过深,会降低代码的可读性。

1.3.3 抽象

隐藏方法的具体实现。从调用方角度来看,并不关心方法是怎么实现的,只需告诉该方法能做什么即可。类比到现实世界,买车的时候,仅关注车提供的功能,并不关注你是怎么做出来的。 本质: 就是复杂世界或复杂系统提供的信息太多了,有些信息是完全没必要关注的。因此,仅关注你所关心的即可。
实现方式: Java中提供了接口和抽象语法
存在意义: 提高代码可扩展性,可读性和可维护性;是处理复杂系统的有效手段。

1.3.4 多态

指子类可以灵活替换父类,需要编程语言特殊语言支持。类似于Java的接口、抽象类等。
存在意义:提高代码的可扩展性,可复用性,是设计模式的基础。可复用指的是如果不采用多态的方式,相同的代码可能需要使用多份。
在这里插入图片描述

1.4 常见的面向对象写为面向过程的示例

1.4.1 Getter和Setter方法的滥用

上面说了,面向对象是通过访问权限控制,隐藏内部数据,仅提供有限的接口给外部使用。但是普通对象的getter和setter方法滥用,就会导致对象中虽然定义属性是private,但实际上是public的操作权限。若类中存在容器对象,,即使只提供getter方法,也可以修改容器中的数据,推荐做法为:

public List<ShoppingCartItem> getItems() {return Collections.unmodifiableList(this.items);
}

1.4.2 全局变量和全局方法的滥用

一般项目中,会写一个大而全的Constants常量类,明显违背了面向对象设计,存在以下缺点:

  1. 影响代码的可维护性。由于这个类是全局的,许多开发人员都会修改,提交冲突概率增大,同时查找比较耗时;
  2. 增加代码的编译时间。这个类全局的,很多地方都会被用到,一旦constants类发生变化,许多依赖它的类都会重新进行编译,非常耗时;
  3. 影响代码的复用性。若某个第三方组件依赖项目中的某一类,而这个类又依赖constants类,导致大量无关的常量被引入进来。

推荐做法:尽量做到职责单一,按照业务的不同,划分不同xxxcConstants类

1.4.3 定义数据和方法相分离的类

就是经常使用的MVC模式,dao层的实体类和service服务类相分离,即基于贫血模型的开发方法。

1.4.4 底层思考过程

现实中,为了完成一个任务,一般会思考,先做什么,后做什么,如何一步步完成任务,这就是典型的面向过程,适合简单系统开发,例如MVC开发模式。而面向对象是自底向上的逻辑,先构建每个任务的模块,然后思考设计类与类之间的交互,最后按照流程组装起来完成任务,适合复杂系统的开发。

二、接口vs抽象类的区别

2.1 定义

  • 接口:指的是定义一组协议或规范。接口通常只定义方法的声明,不做具体的实现;接口不能创建对象;实现接口时,必须实现所有的方法;
  • 抽象类:是对成员变量和方法的抽象。抽象类不允许被实例化;抽象类可以包含属性和方法;子类必须实现抽象类的所有抽象方法

2.2 解决问题类型

2.2.1 接口

主要解决的是has-a问题,降低代码之间的耦合性,将接口和实现相分离,提高代码的扩展性。接口代表自上而下的设计思路。

2.2.2 抽象类

主要解决的是is-a问题,提高代码的复用性。抽象类代表自下而上的设计思路。
为什么不直接使用普通类的?原因在于:抽象类的抽象方法强制开发人员必须实现,而普通类则没有要求,那么可能会造成某些方法应该被实现,却没有被实现,不利于代码的可读性,同时无法使用多态特性

2.3 实际使用场景

若要表示is-a关系,且为了提高代码的复用性,则使用抽象类;
若要表示has-a关系,且为了提高代码的扩展性,则使用接口。

三、基于接口而非实现编程的讨论

概述:基于接口而非实现编程,又称```基于抽象而非实现````编程,将接口和实现相分离,隐藏不稳定的实现,暴露稳定的接口实现解耦,增加代码的可扩展性。

实现步骤

  1. 接口函数的命名要抽象。反例:uploadAliyun(), 正例:upload()
  2. 暴露通用统一的方法。
    11.png
  3. 封装具体实现细节

什么场景下使用该原则?
该条原则设计的初衷是面对未来变化场景。若某个业务场景的实现只有一种方式,就没必要设计接口;否则,就需要设计接口。

思考:
接口的思想:封装隔离,将调用和创建相互分离。
封装:通常封装是指对数据的封装,但是这里的封装是指对被隔离体的行为的封装,或者是
对被隔离体的职责的封装
隔离:隔离指的是外部调用和内部实现,外部调用只能通过接口进行调用,而外部调用是不知道内部具体实现的,也就是说外部调用和内部实现是被接口隔离开的。
使用接口的好处】:由于将外部调用和内部实现隔离开来,只要接口定义的行为不变,内部实现
的变化就不会影响到外部系统的调用,使得系统更加灵活,具有更好的扩展性和可维护性,同时具体的实现可以动态切换,而不会影响到系统,即【接口是系统可插拔性的保证】。例如:
List<String> list = new ArrayList<>(),仅是使用了Java的多态语法,使用方即客户端不仅知道接口,还知道具体的实现,是不满足面向接口编程的。解决方案: 简单工厂模式来解决

四、组合和继承的讨论

继承虽然可以提高代码的可复用性,但存在继承层次过深,导致代码难维护的问题。
可以通过组合,接口和委托三个技术手段来解决。适用场景:

  1. 若类之间的继承结构稳定,且继承层次比较浅(最多有两层),继承关系不复杂,考虑使用继承;
  2. 否则,尽量使用组合来替代继承。

例子: A类和B类之间没有继承关系,但是都用到了URL拼接和分割的功能。若为了代码复用,抽出一个父类,会影响代码的可读性,此时使用组合则更加合理,更加灵活。

五. 如何提高代码的可复用性

  • 减少代码耦合。耦合代码严重的话,等想抽取可复用代码时,会导致大量的代码被修改,增加了bug的概率;
  • 满足单一职责原则。职责越单一,可复用性越高;
  • 模块化。对模块,类或函数,要善于封装和抽取通用的代码;
  • 通用代码下沉。指的是代码要进行合理的分层,越底层的代码要封装的足够抽象和通用,这样可以最大程度的增加可复用性;
  • 利用继承,多态,抽象以及封装的思想,来设计代码
  • 适度的使用设计模式

编写可复用性代码的思考:遵循Rule of Three原则,即第一次写代码不考虑复用性,第二次遇到复用场景时,再考虑重构进行复用。

六、设计模式本质思考

设计模式的本质就是对某个固定场景的最优解,这个最优解是一套经典模板,并不是所有的场景都适合。目的是为了修改少量代码就可以适应需求的变化。学习设计模式需要进行如下思考:

  1. 适用场景
  2. 优点和缺点。不使用设计模式在面对未来变化时,有哪些不足;使用设计模式在面对未来变化时,有哪些好处
  3. 满足哪些设计原则
  4. 稳定点和不稳定点是什么。所谓稳定点指的是不变的点,不稳定点指的是变化的点

七、设计模式,原则以及目标之间的关系

在这里插入图片描述

相关文章:

三、设计模式相关理论总结

一、面向对象编程 1.1 概述 简称Object Oriented Program(OOP)&#xff0c;指以类或对象作为基础组织单元&#xff0c;遵循封装、继承、多态以及抽象等特性&#xff0c;进行编程。其中面向对象不一定遵循封装、继承、封装和多态等特性&#xff0c;只是前人总结的套路规范&…...

鸿蒙 WiFi 连接 流程

那当界面上显示扫描到的所有Ap时&#xff0c;我们选择其中的一个Ap发起连接&#xff0c;看下代码流程是怎样的。 // applications/standard/settings/product/phone/src/main/ets/model/wifiImpl/WifiModel.tsconnectWiFi(password: string) {let apInfo this.userSelectedAp…...

golang 创建unix socket http服务端

服务端 package mainimport ("fmt""net""net/http""os" )func main() {http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {w.Write([]byte("hello"))})http.HandleFunc("/world", …...

annaconda如何切换当前python环境

annaconda默认的python环境是base&#xff1a; 把各种项目的依赖都安装到base环境中不是一个好的习惯&#xff0c;比如说我们做爬虫项目和做自动化测试项目等所需要的依赖是不一样的&#xff0c;我们可以将为每个项目创建自己的环境&#xff0c;在各自的环境中安装自己的依赖&…...

gtkmm 与 Cambalache 与 Gtk::Builder (新手向)_

文章目录 前言Cambalache检查Xml.cpp文件如何写才能显示UI首先creat获取ui里的对象显示 前言 新手刚刚使用时的笔记 Cambalache检查Xml 窗口右键inspect UI Definition切换到Xml视图, 可以全选复制粘贴到你的ui文件里, Cambalache 只能保存为.cmb工程文件, 导出也不知道导出…...

uniapp小程序端使用计算属性动态绑定style样式踩坑

踩坑点: 使用uniapp编译小程序端动态绑定复杂style使用计算属性方式&#xff0c;return必须返回json字符串格式&#xff0c;不能返回object&#xff0c;否则会不起作用。 代码总览 视图层 逻辑层&#xff08;注意这里是使用的计算属性哈&#xff09; 这里我封装成了一个个性化…...

计算机网络概念、组成、功能和分类

文章目录 概要1.怎么学习计算机网络2.概念3.功能、组成4.工作方式、功能组成5.分类 概要 概念、组成、功能和分类 1.怎么学习计算机网络 2.概念 通信设备&#xff1a;比如路由器、路由器 线路&#xff1a;将系统和通信设备两者联系的介质之类的 计算机网络是互连的、自治的的计…...

MyBatisPlus基础操作之增删改查

目录 一、基本使用 1.1 插入数据 1.2 删除操作 1.3 更新操作 二、条件构造器Wrapper 2.1 常用AbstractWrapper方法 2.1.1 示例一 2.2.2 示例二 2.2.3 示例三 2.2 常用QueryWrapper方法 2.2.1 示例一 2.2.2 示例二 2.2.3 示例三&#xff08;常用&#xff09; 2.3 常…...

视频处理学习笔记1:YUYV422、NV12和h264

最近因为工作关系在恶补视频相关知识点&#xff0c;在此做一记录便于日后复习。 以下均是个人学习经验总结&#xff0c;可能存在错误和坑&#xff0c;欢迎大佬指教。 工作中用到的是YUYV422存储格式。存储的就是裸流YUYV422格式文件。 YUYV422是两个像素点共用一个UV分量&am…...

CTFshow web(命令执行29-36)

?ceval($_GET[shy]);&shypassthru(cat flag.php); #逃逸过滤 ?cinclude%09$_GET[shy]?>&shyphp://filter/readconvert.base64-encode/resourceflag.php #文件包含 ?cinclude%0a$_GET[cmd]?>&cmdphp://filter/readconvert.base64-encode/…...

PyTorch深度学习实战(23)——从零开始实现SSD目标检测

PyTorch深度学习实战&#xff08;23&#xff09;——从零开始实现SSD目标检测 0. 前言1. SSD 目标检测模型1.1 SSD 网络架构1.2 利用不同网络层执行边界框和类别预测1.3 不同网络层中默认框的尺寸和宽高比1.4 数据准备1.5 模型训练 2. 实现 SSD 目标检测2.1 SSD300 架构2.2 Mul…...

【附代码】NumPy加速库NumExpr(大数据)

文章目录 相关文献测试电脑配置数组加减乘除数组乘方Pandas加减乘除总结 作者&#xff1a;小猪快跑 基础数学&计算数学&#xff0c;从事优化领域5年&#xff0c;主要研究方向&#xff1a;MIP求解器、整数规划、随机规划、智能优化算法 如有错误&#xff0c;欢迎指正。如有…...

4、安全开发-Python-蓝队项目流量攻击分析文件动态监控图片隐写技术

用途&#xff1a;个人学习笔记&#xff0c;有所借鉴&#xff0c;欢迎指正&#xff01; 总结&#xff1a; &#xff08;1&#xff09;使用python脚本Scapy库实现指定网卡的流量抓包分析 &#xff08;2&#xff09;使用python脚本Watchdog实现指定目录文件行为监控 &#xff08;…...

MySQL 日志管理

4.6&#xff09;日志管理 MySQL 支持丰富的日志类型&#xff0c;如下&#xff1a; 事务日志&#xff1a;transaction log 事务日志的写入类型为 "追加"&#xff0c;因此其操作为 "顺序IO"&#xff1b; 通常也被称为&#xff1a;预写式日志 write ahead…...

Python CSV文件读取和写入

本文主要为Python 实现CSV文件读取和写入操作。 CSV文件写入和读取 因为没有现成的csv文件&#xff0c;所以csv的顺序为先写入后读取。 写入 创建csv文件并把数据写入&#xff0c;有两种实现方式&#xff1a;直接插入所有行和插入单行。 示例如下&#xff1a; import csv i…...

如何使用C#调用LabVIEW算法

新建一个工程 这是必须的&#xff1b; 创建项目 项目 点击完成&#xff1b; 将项目另存为&#xff1b;方便后续的使用&#xff1b; 创建 一个测试VI 功能很简单&#xff0c;用的一个加法&#xff1b;将加数A&#xff0c;B设置为输入&#xff0c;和C设置为输出&#xff0c;…...

调用百度文心AI作画API实现中文-图像跨模态生成

作者介绍 乔冠华&#xff0c;女&#xff0c;西安工程大学电子信息学院&#xff0c;2020级硕士研究生&#xff0c;张宏伟人工智能课题组。 研究方向&#xff1a;机器视觉与人工智能。 电子邮件&#xff1a;1078914066qq.com 一&#xff0e;文心AI作画API介绍 1. 文心AI作画 文…...

JAVA SpringBoot中使用redis的事务

目录 一、Java语言介绍 二、SpringBoot框架介绍 三、Redis缓存介绍 四、什么是redis的事务 一、Java语言介绍 Java是一种广泛使用的高级编程语言,由Sun Microsystems公司于1995年推出。它的设计目标是要求“一次编写,到处运行”&#xff08;Write Once, Run Anywhere, WOR…...

docker部署自己的网站wordpress

目录 安装 1.创建目录 2.创建并启动mysql 3.创建并启动wordpress 使用 1.设置语言 2.设置基础信息 3.首页 安装 1.创建目录 mkdir -p /opt/wordpress/{db,data} 2.创建并启动mysql docker run -d --name my_mysql --restart always -e MYSQL_ROOT_PASSWORD123456 -e …...

基于ISO13400 (DoIP) 实现车辆刷写

近年来&#xff0c;在整车研发中基于以太网实现车辆高带宽通讯无疑是人们热议的话题。无论是车内基于车载以太网来减少线束成本&#xff0c;实现ADAS、信息娱乐系统等技术&#xff0c;还是基于新的电子电气架构以及远程诊断需求来实现以太网诊断&#xff08;DoIP&#xff09;&a…...

Chrome 沙箱逃逸 -- Plaid CTF 2020 mojo

文章目录 前置知识参考文章环境搭建题目环境调试环境 题目分析附件分析漏洞分析OOBUAF 漏洞利用总结 前置知识 Mojo & Services 简介 chromium mojo 快速入门 Mojo docs Intro to Mojo & Services 译文&#xff1a;利用Mojo IPC的UAF漏洞实现Chrome浏览器沙箱逃逸原文…...

汇编笔记 01

小蒟蒻的汇编自学笔记&#xff0c;如有错误&#xff0c;望不吝赐教 文章目录 笔记编辑器&#xff0c;启动&#xff01;debug功能CS & IPmovaddsub汇编语言寄存器的英文全称中英对照表muldivandor 笔记 编辑器&#xff0c;启动&#xff01; 进入 debug 模式 debug功能 …...

C语言:矩阵中的最小元素

题目描述 给定一个5X5的整数矩阵&#xff0c;找出其中最小的元素&#xff0c;输出所在的行号、列号和元素值&#xff0c;其中行号和列号都从0开始。 例如&#xff0c;有矩阵&#xff1a; 5 86 53 50 18 25 67 79 44 68 79 63 24 84 100 42 30 59 47 37 28 10 32 23 81 其中最小…...

【原创】MQTT开发笔记(四)- 压力测试

一、前言 Jmeter 是 apache 公司基于 java 开发的一款开源压力测试工具&#xff0c;体积小&#xff0c;功能全&#xff0c;使用方便&#xff0c;是一个比较轻量级的测试工具&#xff0c;使用起来非常简 单。因为 jmeter 是 java 开发的&#xff0c;所以运行的时候必须先要安装 …...

vue 引入 百度地图API 和 路书

公司项目中&#xff0c;偶尔都会涉及到地图的使用&#xff0c;这里以百度地图为例&#xff0c;我们梳理一下引用流程及注意点 账号和获取密钥 百度地图示例 百度地图 类参考 1、账号和获取密钥 // api.map.baidu.com/api?typewebgl&v3.0&ak您的密钥<script type…...

【QT+QGIS跨平台编译】之二十六:【SpatialIndex+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、SpatialIndex介绍二、文件下载三、文件分析四、pro文件五、编译实践一、SpatialIndex介绍 SpatialIndex是一个用于高效处理空间数据的C++库,基于R树索引结构实现。它提供了一系列的空间操作和查询算法,能够快速地对大规模空间数据进行检索和分析。 SpatialInd…...

SQL在云计算中的新角色:重新定义数据分析

文章目录 1. 云计算与数据分析的融合2. SQL在云计算中的新角色3. 分布式SQL查询引擎4. SQL-on-Hadoop解决方案5. SQL与其他数据分析工具的集成6. 实时数据分析与SQL7. SQL在云数据仓库中的角色8. 安全性与隐私保护9. SQL的未来展望《SQL数据分析实战&#xff08;第2版&#xff…...

云安全的基本概念(基本目标与指导方针)

目录 一、云安全概念概述 1.1 概述 二、云安全的基本目标 2.1 安全策略开发模型 2.1.1 信息安全三元组 2.1.1.1 保密性(Confidentiality) 2.1.1.2 完整性(Integrity) 2.1.1.3 可用性(Availability) 2.1.2 信息安全三元组的局限性 2.2 其他信息安全属性 2.2.1 真实性 …...

猫头虎分享已解决Bug || docker: Error response from daemon: network not found

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …...

《幻兽帕鲁》攻略:0基础入门及游戏基础操作 幻兽帕鲁基础设施 幻兽帕鲁基础攻击力 Mac苹果电脑玩幻兽帕鲁 幻兽帕鲁加班加点

今天就跟大家聊聊《幻兽帕鲁》攻略&#xff1a;0基础入门及游戏基础操作。 如果想在苹果电脑玩《幻兽帕鲁》记得安装CrossOver哦。 以下纯干货&#xff1a; CrossOver正版安装包&#xff08;免费试用&#xff09;&#xff1a;https://souurl.cn/Y1gDao 一、基础操作 二、界面…...