设计模式篇章(1)——理论基础

设计模式:在软件开发中会面临许多不断重复发生的问题,这些问题可能是代码冗余、反复修改旧代码、重写以前的代码、在旧代码上不断堆新的代码(俗称屎山)等难以扩展、不好维护的问题。因此1990年有四位大佬(GoF组合)合作出了一本书,叫做《设计模式:可复用面向对象软件的基础》,它比较完美地解决了在软件工程当中所遇到的上述问题,即给出了如果遇到上述问题的标准答案!这本书提出了23种设计模式供后人学习,正确使用设计模式有如下优点:

  • 程序设计标准化,工程化,开发效率大大提高,大家遵守统一规范。
  • 设计模式的代码可用性高、可读性强(读者掌握设计模式的基础上)、可靠性好、可维护性强、灵活性好等特点。

设计模式的分类

创建者模式

这个设计模式主要思考如何创建一个对象,如何将对象的创建与使用分离。一般初级程序员都是new一个对象,然后紧接着使用这个对象,在某些场景中这样子是有问题的,需要使用创建者模式替代的(例如使用单例模式)。设计模式中提供了五种创建模型,分别是单例、原型、工厂方法、抽象工厂方法、创建者五种模式。

结构型模式

这个设计模式主要思考的是如何将对象进行合理的布局来组成一个更大的功能体或者结构体,这个现在讲有点抽象,用大白话讲就是利用现有的对象进行组合或者配合,使得组合后的这个系统更加好。好是相对于不使用设计模式,按照自己的堆屎山的逻辑堆成一个冗余的系统。结构型模式包括:代理模式、适配器模式、桥接模式、装饰模式、外观模式、享元模式、组合模式七种设计模式。

行为型设计模式

这个设计模式主要思考的是如何分配对象的职责和将对象之间相互协作完成单个对象无法完成的任务,这个与结构型模式有点像,结构型可以理解为静态的组合,例如将不同的组件拼起来成为一个更大的组件;而行为型更是一种动态或者具有某个动作触发的事件,具有一定行为的设计模式。现在不清楚没关系,学完23种设计模式再回头看就能理解了。行为型模式包括:模板方法模式、策略模式、命令模式、职责链模式、状态模式、观察者模式、中介者模式、迭代器模式、访问者模式、备忘录模式、解释器模式共11种。

先搞懂UML中的类图

​ 统一建模语言(Unified Modeling Language,UML)是用来设计软件的可视化建模语言。它的特点是简单、统一、图形化、能表达软件设计中的动态与静态信息。UML 从目标系统的不同角度出发,定义了用例图、类图、对象图、状态图、活动图、时序图、协作图、构件图、部署图等 9 种图。这里不需要管这么多,只需要懂得类图即可。类图(Class diagram)是显示了模型的静态结构,特别是模型中存在的类、类的内部结构以及它们与其他类的关系等。类图不显示暂时性的信息。类图是面向对象建模的主要组成部分

​在UML类图中,类使用包含类名、属性(field) 和方法(method) 且带有分割线的矩形来表示,比如下图表示一个Employee类,它包含name,age和address这3个属性,以及work()方法。
在这里插入图片描述
属性/方法名称前加的加号和减号表示了这个属性/方法的可见性,UML类图中表示可见性的符号有三种:

  • +:表示public
  • -:表示private
  • #:表示protected

类图之间关系的表示方式

关联关系

关联关系是对象之间的一种引用关系,用于表示一类对象与另一类对象之间的联系,即一个类属性对象的引用关系。在Java中可以理解为依赖关系或者引用关系。

  • 单向关联

    使用单向黑箭头表示,被指向的类表示被引用了,如下地址类被顾客类所引用,通过让Customer类持有一个类型为Address的成员变量类实现:
    在这里插入图片描述

  • 双向关联

    使用无方向线条表示,两个相连接的类可以互为对方的成员变量,下图中在Customer类中维护一个List<Product>,表示一个顾客可以购买多个商品;在Product类中维护一个Customer类型的成员变量表示这个产品被哪个顾客所购买:
    在这里插入图片描述

  • 自关联
    使用单向黑箭头表示,下图的意思就是Node类包含类型为Node的成员变量,也就是“自己包含自己”:

    在这里插入图片描述

  • 聚合关系
    聚合关系可以用带空心菱形的实线来表示,菱形指向整体,聚合关系是关联关系的一种,是强关联关系,是整体和部分之间的关系。聚合关系也是通过成员对象来实现的,其中成员对象是整体对象的一部分,但是成员对象可以脱离整体对象而独立存在。
    注意:这里很容易理解为单向关联关系,区别如下:从整体与部分来理解,单向关联关系是类与类之间的联接,它使一个类知道另一个类的属性和方法。它是依赖关系相对聚合关系更加弱的一种关系。而聚合关系更加强调整体与部分,如下教师知识一个学校的一部分,一个学校不可以没有教师,但是没有学校教师依旧可以存在。而顾客可以有地址,也可以不填地址。单向关联关系是一种相对较弱的关系,其中一个类知道另一个类的存在;而聚合关系则表示更强的整体与部分之间的关系,其中被包含的类是整体的一部分。总之聚合关系依赖关系更加强,强调整体与部分! 在这里插入图片描述

  • 组合关系
    组合关系使用黑色菱形箭头表示,菱形指向整体。组合关系非常好理解,他和聚合关系的明显区别就是被包含的类不可用脱离整体类而存在。聚合关系中的教师类可以脱离学校而存在,就像鼠标类可以脱离电脑类而单独存在,但是汽车方向盘类不可以脱离汽车类而存在。就像下图所示是头和嘴的关系图: 在这里插入图片描述

依赖关系

依赖关系使用带箭头的虚线来表示,箭头从使用类指向被依赖的类。依赖关系是一种使用关系,它是对象之间耦合度最弱的一种关联方式,是临时性的关联。在代码中,某个类的方法通过局部变量、方法的参数或者对静态方法的调用来访问另一个类(被依赖类)中的某些方法来完成一些职责。如下图所示,司机和汽车的关系图,汽车类只是司机类的一个参数|局部变量:
在这里插入图片描述

继承关系

泛化关系用带空心三角箭头的实线来表示,箭头从子类指向父类。继承关系是对象之间耦合度最大的一种关系,表示一般与特殊的关系,是父类与子类之间的关系,是一种继承关系。在代码实现时,使用面向对象的继承机制来实现泛化关系。例如,Student 类和 Teacher 类都是 Person 类的子类,其类图如下图所示:

在这里插入图片描述

实现关系

实现关系使用带空心三角箭头的虚线来表示,箭头从实现类指向接口。实现关系是接口与实现类之间的关系。在这种关系中,类实现了接口,类中的操作实现了接口中所声明的所有的抽象操作。例如,汽车和船实现了交通工具,其类图如图 所示。
在这里插入图片描述

软件设计原则

在软件开发中,为了提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性,程序员要尽量根据6条原则来开发程序,从而提高软件开发效率、节约软件开发成本和维护成本。

开闭原则

开闭原则的意思是对扩展开放、对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类。但是尽量不要使用抽象类,而实现接口类!组合优于继承,假设我们将燕子、老鹰抽象为一个鸟类,那么这个类就有鸟的一些共性,例如都有飞的方法。到目前为止,这个系统能够安稳地运行。但是现在出现了另外一个动物鸵鸟,现在开发者非常纠结到底要不要继承鸟这个类。这个列子再开发中更加常见,有很多本身就比较抽象的对象,继承本来就是写死了一些东西。如果使用接口,就无需烦恼了,需要什么实现什么,就像搭积木一样组合起来就行。例如鸵鸟对象,我们可以让它实现飞的接口、地上跑的接口等,组合起来就行。因此,开闭原则总结就是如果要升级某个功能或者重写某个需求,先看看能不能通过实现接口重写,而不是直接修改代码,这个在设计模式中有很多地方都体现了这一点。

里氏代换原则

子类可以扩展父类的功能,但不能改变父类原有的功能。换句话说,子类继承父类时,除添加新的方法完成新增功能外,尽量不要重写父类已经实现的方法。如果通过重写父类的方法来完成新的功能,这样写起来虽然简单,但是整个继承体系的可复用性会比较差,特别是运用多态比较频繁时,程序运行出错的概率会非常大。

依赖倒转原则

高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。例子如下:
在这里插入图片描述

假设电脑仅由CPU、硬盘、内存卡三个设备组成,上图是错误的,因为抽象不应该依赖细节,细节应该依赖抽象。即三个属性应该都是抽象的,也就是多态,而不应该写死(具体化),应该改成下面的,具体的CPU、硬盘、内存卡知识对接口的实现,Computer而不直接依赖具体实现:

在这里插入图片描述

接口隔离原则

实现类不应该被迫依赖于它不使用的方法;一个类对另一个类的依赖应该建立在最小的接口上。典型例子就是组合大于继承的列子,使用继承违背了接口隔离原则,而合理使用接口不违背,我们需要创建一个黑马品牌的安全门,该安全门具有防火、防水、防盗的功能。可以将防火,防水,防盗功能提取成一个接口,形成一套规范。类图如下:

在这里插入图片描述
上面的设计我们发现了它存在的问题,黑马品牌的安全门具有防盗,防水,防火的功能。现在如果我们还需要再创建一个传智品牌的安全门,而该安全门只具有防盗、防水功能呢?很显然如果实现SafetyDoor接口就违背了接口隔离原则,那么我们如何进行修改呢?看如下类图:

在这里插入图片描述

迪米特法则

迪米特法则又叫最少知识原则。只和你的直接朋友交谈,不跟“陌生人”说话(Talk only to your immediate friends and not to strangers)。

其含义是:如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。迪米特法则中的“朋友”是指:当前对象本身、当前对象的成员对象、当前对象所创建的对象、当前对象的方法参数等,这些对象同当前对象存在关联、聚合或组合关系,可以直接访问这些对象的方法。否则应该使用第三方对象负责调用。下面看一个例子来理解迪米特法则。

【例】明星与经纪人的关系实例

明星由于全身心投入艺术,所以许多日常事务由经纪人负责处理,如和粉丝的见面会,和媒体公司的业务洽淡等。这里的经纪人是明星的朋友,而粉丝和媒体公司是陌生人,所以适合使用迪米特法则。

类图如下:

在这里插入图片描述

合成复用原则

合成复用原则是指:尽量先使用组合或者聚合等关联关系来实现(实现接口得到组合对象),其次才考虑使用继承关系来实现。通常类的复用分为继承复用和合成复用两种。

继承复用虽然有简单和易实现的优点,但它也存在以下缺点:

  1. 继承复用破坏了类的封装性。因为继承会将父类的实现细节暴露给子类,父类对子类是透明的,所以这种复用又称为“白箱”复用。
  2. 子类与父类的耦合度高。父类的实现的任何改变都会导致子类的实现发生变化,这不利于类的扩展与维护。
  3. 它限制了复用的灵活性。从父类继承而来的实现是静态的,在编译时已经定义,所以在运行时不可能发生变化。

采用组合或聚合复用时,可以将已有对象纳入新对象中,使之成为新对象的一部分,新对象可以调用已有对象的功能,它有以下优点:

  1. 它维持了类的封装性。因为成分对象的内部细节是新对象看不见的,所以这种复用又称为“黑箱”复用。
  2. 对象间的耦合度低。可以在类的成员位置声明抽象。
  3. 复用的灵活性高。这种复用可以在运行时动态进行,新对象可以动态地引用与成分对象类型相同的对象。

下面看一个例子来理解合成复用原则

【例】汽车分类管理程序

汽车按“动力源”划分可分为汽油汽车、电动汽车等;按“颜色”划分可分为白色汽车、黑色汽车和红色汽车等。如果同时考虑这两种分类,其组合就很多。类图如下:
在这里插入图片描述 从上面类图我们可以看到使用继承复用产生了很多子类,如果现在又有新的动力源或者新的颜色的话,就需要再定义新的类。我们试着将继承复用改为聚合复用看一下。
在这里插入图片描述

参考自黑马设计模式学习资料

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ant design pro 5 企业级后台前端框架自定义根路径设置,解决public文件夹下资源在打包部署后出现找不到的问题

关于ant design pro v5的开箱使用方法见&#xff1a;开箱即用的企业级数据和业务管理中后台前端框架Ant Design Pro 5的开箱使用和偏好配置-CSDN博客 在开发过程中为了方便我们可能会将部分静态资源如logo等放入public文件夹&#xff0c;但在设置站点根路径后&#xff0c;publi…

5.云原生安全之ingress配置域名TLS证书

文章目录 cloudflare配置使用cloudflare托管域名获取cloudflare API Token在cloudflare中配置SSL/TLS kubesphere使用cert-manager申请cloudflare证书安装证书管理器创建Secret资源创建cluster-issuer.yaml创建cert.yaml申请证书已经查看申请状态 部署harbor并配置ingress使用证…

iec61850规约原理和工作原理

规约下载 https://products.iec.ch/view/search/all 规约整体介绍 ** IEC104和IEC61850的区别 ** modbus和IEC61850有什么区别 IEC61850简要介绍 变电站通信体系IEC61850将变电站通信体系分为3层站控层、间隔层、过程层。 IEC61850标准的服务实现主要分为三个部分&#xff…

运输层

title: 运输层 date: 2023-12-24 14:17:55 tags: 知识总结 categories: 计算机网络 运输层和网络层的联系和区别 物理层、数据链路层以及网络层它们共同解决了将主机通过异构网络互联起来所面临的问题&#xff0c;实现了主机到主机的通信&#xff0c;但实际上&#xff0c;在计…

奋楫扬帆,奔赴新程 | 2023 年图扑大事记回顾,与您携手共迎 2024

2023.01 工信部公示了 2022 年度智能制造示范工厂揭榜单位和优秀场景名单。图扑软件和上海洲邦合作建设的宁波甬友数字孪生工厂被评为优秀场景&#xff0c;全国共有 369 个智能制造典型场景入选。 2023.01 在第十一届中国创新创业大赛全国赛&#xff08;新一代信息技术&#…

idea 弹框提示:Server‘s certificate is not trusted 解决办法

如图所示&#xff1a; 引起这个的根本原因:是因为你破解了idea&#xff0c;在本地hosts配置了映射&#xff0c;然后idea检测出来弹出警告 服务器证书不可用。所以在弹出这个框。 解决方法&#xff1a; 打开idea--->File-->Settings-->Tools-->点击Server Certifi…

anaconda navigator卡在loading user解决办法

01问题 打开anaconda navigator特别慢&#xff0c;卡在loading user 02查找原因 (1)关闭anaconda的所有进程 (2)打开anaconda prompt&#xff0c;输入anaconda-Navigator回车&#xff0c;即可通过报错查看原因。 QMimeDatabase: Error loading internal MIME data

jdk和IDEA教育版下载和安装详解

前言 研究生专业是通信系统,为了寻找实习于是在研二时期学习java。但是在学习java的过程中没有进行系统总结,很多知识点或者一些细节已经忘记。由于工作找的是某行软件中心的软件开发。准备在毕业前对java知识进行系统性学习。本专栏将从零基础开始,从最简单的jdk和IDEA下载…

python入门第一讲:认识python

目录 什么是计算机 什么是编程 编程语言有哪些 python是咋来的 python能干啥 python的优缺点 什么是计算机 什么叫计算机&#xff0c;当你把问这个问题问家里的老人的时候&#xff0c;他们很可能指着计算器告诉你说&#xff0c;这个就是计算机&#xff0c;这个很明显&am…

一文上手ThreadLocal使用和原理

什么是ThreadLocal?它有什么用&#xff1f; 当我们某个类需要被多线程共享的时候&#xff0c;我们就可以使用ThreadLocal关键字&#xff0c;ThreadLocal可以为每个线程创建这个变量的副本并存到每个线程的存储空间中(关于这个存储空间后文会展开讲述)&#xff0c;从而确保共享…

输出回文数-第11届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第23讲。 输出回文数&#…

数据分析概述

数据分析概述 在当今数字化的时代&#xff0c;数据已经成为我们周围不可忽视的存在。从商业领域到医疗行业&#xff0c;从科学研究到政府治理&#xff0c;数据的涌现为我们提供了前所未有的信息资源。然而&#xff0c;要从这个庞大的信息海洋中获取有意义的见解并做出明智的决策…

OpenCV-14图片的四则运算和图片的融合

一、图片的四则运算 1. 加法运算 通过使用API add来执行图像的加法运算 cv2.add&#xff08;src1&#xff0c; src2&#xff09;需要再其中传入两张图片。 图片就是矩阵&#xff0c;图片的加法运算就是矩阵的加法运算。 因此加法运算中要求两张图的shape必须是相同的。 首…

2023我的编程之旅-地质人的山和水

引言 大家好&#xff0c;我是搞地质的。外行人有的说我们游山玩水&#xff0c;有的说我们灰头土脸&#xff0c;也有的说我们不是科学。 而我说&#xff0c;这是一门穷极一生青春&#xff0c;值得奉献的行业。这是一门贴近民生&#xff0c;又拥抱自然的学科。他的真理性在于探…

excel 插件:Rainbow Analyst Crack

一个插件中包含四种 EXCEL 审核工具检测并修复隐藏的电子表格错误 不要满足于更少&#xff0c;四种领先的电子表格审计工具合二为一 Rainbow Analyst&#xff08;因其对颜色编码的独特强大使用而得名&#xff09;结合了世界级电子表格审核功能的多个领域&#xff1a; Excel™ …

【Spring实战】14 Web表单校验

文章目录 1. 依赖2. 实体类3. 控制器4. 页面5. 启动6. 验证1&#xff09;访问页面2&#xff09;后台校验 7. 优点8. 代码详细总结 在 Web 应用中&#xff0c;表单是用户与后端交互的主要界面之一。为了确保数据的有效性和一致性&#xff0c;我们经常需要对提交的表单数据进行验…

一文教会git如何配置多SSH Key(Github+Gitlab)

一文教会git如何配置多SSH Key&#xff08;GithubGitlab&#xff09; 对于工作了的伙伴来说&#xff0c;大家经常会配置多个SSH Key&#xff1a; SSH拉取的仓库不会反复的要求输入github用户名密码来验证自己的身份需要将公司的Gitlab和个人的Github区分开 我这里以Mac电脑为例…

Debezium发布历史46

原文地址&#xff1a; https://debezium.io/blog/2019/02/05/debezium-0-9-0-final-released/ 欢迎关注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻译&#xff0c;仅供参考&#xff0c;笔芯笔芯. Debezium 0.9.0.Final 发布 2019 年 2 月 5 日 作者&#xff1a; G…

matplotlib颜色合集——各种常见简单图形(上)

一、.颜色配图表 图文颜色引用&#xff1a;建站教程 - FINTHON 二、折线图 jupyter notebook 简介plot() 2.1折线图参数 plt.plot(*args, scalexTrue, scaleyTrue, dataNone, **kwargs) 2.2、参数介绍 x&#xff1a;X轴数据&#xff0c;列表或数组&#xff0c;可选。 y&a…

没有Kubernetes也可以玩转Dapr?

一、NameResolution组件 虽然Dapr提供了一系列的编程模型&#xff0c;比如服务调用、发布订阅和Actor模型等&#xff0c;被广泛应用的应该还是服务调用。我们知道微服务环境下的服务调用需要解决服务注册与发现、负载均衡、弹性伸缩等问题&#xff0c;其实Dapr在这方面什么都没…
最新文章