【设计模式-1】UML和设计原则

news2024/11/18 18:25:00

说明:设计模式(Design Pattern)对于软件开发,简单来说,就是软件开发的套路,固定模板。在学习设计模式之前,需要首先学习UML(Unified Modeling Language,统一建模语言)和面向对象设计的七大原则。

UML

设计模式在代码开发之前,先需要使用设计图的方式表现出来,UML就是生产设计图的语言,也就是模型语言。UML的结构有视图(View)、图(Diagram)、模型元素(Model Element)、通用机制(General Mechanism),这里不做过深的介绍,只介绍类图和类之间的关系。

类图(Class Diagram)

结构

一般来说,一个类由三个部分组成:类名、属性和方法。如下这个类图:
在这里插入图片描述

  • 类名:Teacher;
  • 属性:name(String)、age(int,默认值是0)、gender(String);
  • 方法:setAge(int age)、getName();

其中,属性和方法前面的符号,分别表示可见性:公有(public)、私有(private)、受保护(protected)分别用“+”、“-”、“#”来表示,在Java中,还有一种包内可见性(package),使用“*”来表示。

对于属性,在属性类型后面加 “= xx”,表示此属性设置默认值为“xx”,表示方式如下:

可见性 名称:类型 [= 默认值]

对于方法,表示方式如下:

可见性 名称([参数列表])[:返回类型]

以上方括号中的部分,表示可有可无;


如果该类是一个接口,类图表示如下:

在这里插入图片描述

其他内容不变,类名使用两个尖括号包裹,也有在类名左上角使用一个类似圆形取卡针标志来表示的,如下:

在这里插入图片描述


类之间关系

类与类之间的关系,分为以下几种:

关联关系

关联,指类与类之间存在联系,可分为双向关联、单向关联、自关联、多重性关联、聚合和组合,如下:


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


如下,表示一个按钮(Button)只能属于一个表单(Form),是一对一的关系,而一个表单,可以有0个或多个按钮;
在这里插入图片描述

常见的多重性关系有:1…1(一对一)、0…* (0对多) 、1…*(1对多)、0…1(0对一)、m…n(多对多);


例如,汽车(Car)与发动机(Engine),发动机是汽车的组成部分,可以独立于汽车存在,并不依赖于汽车;
在这里插入图片描述


例如,头(Head)与眼睛(Eye),眼睛是头的组成部分,但是眼睛不能单独出来,头没有了眼睛也就没有了;
在这里插入图片描述

依赖关系;

例如,驾驶员(Driver)与车(Car)的关系,驾驶员依赖于车,没有车就无法使用驾驶方法;
在这里插入图片描述

泛化关系;

泛化关系,就是继承关系,如下,学生类(Student)和教师类(Teacher)继承于人类(Person);
在这里插入图片描述

实现关系;

实现关系,顾名思义,如下,船(Ship)与车(Car)实现于交通工具接口(Vehicle),并实现其移动方法(move);

在这里插入图片描述

其他

实际上,UML的图远不止这些,还有用例图(Use Case Diagram)、对象图(Object Diagram)、包图(Package Diagram)等加上类图共13个,但是类图用的最多。

在我手边的《设计模式》(第二版,清华大学出版社,第5页,刘伟著)中,作者引用了Martin Fowler著作中的一段话,“If someone were to come up to you in a dark alley and say, ‘Psst, wanna see a UML diagram?’ that diagram would probably be a class diagram.The majority of UML diagrams Isee are class diagrams.”(“如果有人在黑暗的小巷中向你走来并对你说:'嘿,想不想看一张UML图?'那么这张图很有可能就是一张类图,我所见过的大部分的UML图都是类图”)


面向对象设计原则

面相对象设计原则,指在程序设计时遵循的规范,有以下七个:

单一职责原则(Single Responsibility Principle,SRP)

单一职责原则定义:一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。

简单来说,就是一个类,应该只干一件事。例如在没有三层架构前,一个请求,从接收、分析、处理,都在一个类里完成,无论这个请求的哪一个环节发生了改变都需要修改代码,可维护性差,代码耦合高。


开闭原则(Open-Closed Principle,OCP)

开闭原则定义:一个软件实体应当对扩展开发,对修改关闭。

就是说,后面如果需要新增需求,可以在不修改源码的基础上,对系统扩展。举个例子,一个管理系统的界面,有许多的记录,许多筛选项,最开始记录的字段少,筛选项也少,后面字段越来越多,需要新增一些筛选条件。

不符合开闭原则的做法:对DTO对象不断地新增筛选项,name(姓名)、age(年龄)、createTime(创建时间)……;

符合开闭原则的做法:在DTO对象里定义一个Map对象condition,这样无论后面新增多少个筛选条件,实体类都不需要修改,只需要在Mapper.xml里面新增筛选字段(condition.字段名)的查询条件即可;

private Map<String, String> condition;

里氏代换原则(Liskov Substitution Principle,LSP)

里氏代换原则可以通俗表述为:在软件中如果能够使用基类(父类)对象,那么一定能够使用其子类对象。


依赖倒转原则(Dependency Inversion Principle,DIP)

依赖倒转原则定义:高层模块不应该依赖底层模块,他们都应该依赖抽象。抽象不应该依赖细节,细节应该依赖于抽象。


接口隔离原则(Interface Segregation Principle,ISP)

接口隔离原则定义:客户端不应该依赖那些它不需要的接口。

就是说,对于接口应该尽可能细化,而不是把一堆接口放到到一个大接口里面。如接口A表示飞行,接口B表示跳跃,接口C表示鸣叫,虽然这三个特性麻雀完全符合,但是不能把这三个接口合并到一个接口D中,然后让麻雀来实现,而是应该隔离开,让具备某种能力的类实现指定的接口。


合成复用原则(Composite Reuse Principle,CRP)

合成服用原则定义:尽量使用对象组合,而不是继承来达到服用的目的。

简单来说,就是类之间的关系,少用继承,尽量使用接口实现或者依赖注入的方式。例如有一个面试题,如何解决ArrayList线程不安全的问题,我所知道的有以下5个方法:

(1)使用CopyOnWriteArrayLis();

(2)使用Collections.synchronizedList();

(3)定义一个类MyArrayList,继承ArrayList,重写其方法,每个方法用synchronized修饰;

(4)定义一个类MyArrayList,类里面定义一个ArrayList,自定义List的增删改查方法,用synchronized修饰,方法里面调用ArrayList对应的方法;

(5)使用Vector(不推荐);

重点是第三个、第四个方法的对比,前者是继承,需要重写父类的方法,后者是设值注入,调用ArrayList的方法,显然后者更加灵活。


迪米特法则(Law of Demeter,LoD)

迪米特法则,又称最少知识原则原则,简单来说,就是指一个软件实体应当尽可能少地与其他实体发生相互作用。这样,当一个模块修改时,就会尽量少地影响其他的模块。

总结

本篇文章内容基本来自《设计模式》(第2版,清华大学出版社,刘伟主编)第1、2章

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

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

相关文章

BAT026:删除当前目录及子目录下的空文件夹

引言&#xff1a;编写批处理程序&#xff0c;实现批量删除当前目录及子目录下的空文件夹。 一、新建Windows批处理文件 参考博客&#xff1a; CSDNhttps://mp.csdn.net/mp_blog/creation/editor/132137544 二、写入批处理代码 1.右键新建的批处理文件&#xff0c;点击【编辑…

MinIO (一)安装并生成windows服务

最近公司要搞文件服务器&#xff0c;所以就研究了下MinIO&#xff0c;在这里做个笔记&#xff0c;研究的不深&#xff0c;记录一下基本使用功能&#xff0c;用到了哪些功能就研究哪些&#xff0c;里面的很多功能没用到。 MinIO 文件在线管理系统 更多详细介绍请参考 官网&am…

微信小程序仿苹果负一屏由弱到强的高斯模糊

进入下面小程序可以体验效果&#xff0c;然后进入更多。查看模糊效果 一、创建小程序组件 二、代码 wxml: <view class"topBar-15"></view> <view class"topBar-14"></view> <view class"topBar-13"></view&…

4-k8s-部署springboot项目简单实践

文章目录 一、部署原理图二、部署实践 一、部署原理图 部门一般都有一个属于自己的私服gitlab服务器&#xff0c;由开发者开发代码&#xff0c;然后上传到私服gitlab然后使用调度工具&#xff0c;如jenkins&#xff0c;去gitlab拉去代码&#xff0c;编译打包&#xff0c;最后得…

Web3D虚拟人制作简明指南

如何在线创建虚拟人? 虚拟人,也称为数字化身、虚拟助理或虚拟代理,是一种可以通过各种在线平台与用户进行逼真交互的人工智能人。 在线创建虚拟人变得越来越流行,因为它为个人和企业带来了许多好处。 通过虚拟助理或代理,您可以以更具吸引力和个性化的方式与客户或受众进…

iOS 中,isa 指针

每个对象都有 isa 指针&#xff0c;指向对象所属的类。例如类 NSString 其实是类对象。 类对象产生于编译期&#xff0c;单例。 类对象有 isa 指针指向对应元类&#xff0c;元类&#xff08;metaclass&#xff09;中保存了创建类对象以及类方法所需的所有信息。 struct objc_…

根据脑图谱获取感兴趣区域的mask

根据脑图谱获取感兴趣区域的mask 1&#xff0c;引入1.1 ASPECT-Atlas 2&#xff0c;获取脑图谱感兴趣区域mask参考&#xff1a; 1&#xff0c;引入 脑影像分析中&#xff0c;我们常常会针对性的对某些感兴趣区域进行分析&#xff0c;而对它们进行分析的前提是获取该区域的mask…

网络社区挖掘-图论部分的基本知识笔记

1 网络社区挖掘定义 网络社区挖掘是指利用数据挖掘技术和机器学习算法&#xff0c;分析社交网络、在线社区或互联网上的各种交互数据&#xff0c;以揭示其中隐藏的模式、关系和信息。这些社区可以是社交媒体平台、在线论坛、博客、微博等&#xff0c;人们在这些平台上进行交流…

vueday01——动态参数

我们现在知道了 v-bind:的语法糖是: v-on:的语法糖是 我们现在来尝试一下&#xff0c;定义一个动态参数模拟点击事件按钮 <div :id"idValue" ref"myDiv">我是待测div{{ resultId }}</div> <button v-on:[eventName]"doSomething&…

wsl使用vscode连接,远程安装C/C++ 拓展时,报错

报错内容&#xff1a; EACCES: permission denied, rename /home/wen/.vscode-server/extensions/.b61b1c7c-f703-4dfd-bdc5-d9a00681c4b7 -> /home/wen/.vscode-server/extensions/ms-vscode.cpptools-1.17.5-linux-x64 解决办法&#xff1a; 升级wsl到wsl2就好了。 &a…

高质量床上用品类网站带手机端的pbootcms模板

模板介绍&#xff1a; 这是一个基于PbootCMS内核开发的床上用品类网站模板&#xff0c;专为床上用品、家用纺织类企业设计和开发。它不仅提供了网站界面简洁简单、易于管理的特点&#xff0c;还附带了测试数据&#xff0c;方便用户进行演示和学习。 模板特点&#xff1a; 采用…

vueday01——文本渲染与挂载

1.定义html样式字符串 const rawHtml "<span stylecolor:red>htmlTest</span>" 2.创建标签&#xff0c;分别渲染普通文本和html文本 <p> 你好<span v-html"rawHtml"></span></p> 3.代码展示 4.结果展示

Springboot视图解析与模板引擎~

视图解析&#xff1a; springboot默认不支持JSP&#xff0c;需要引入第三方模板引擎技术实现页面渲染 视图处理方式&#xff1a;转发&#xff0c;重定向&#xff0c;自定义视图 thymeleaf的使用&#xff1a; 1&#xff1a;引入starter <dependency><groupId>o…

windows环境下定时备份删除mysql文件bat脚本

1、新建一个xx.bat结尾的文件复制已下内容 rem ******MySQL backup start******echo off::删除一周前的备份数据forfiles /p "D:\mysql_backup" /m backup_*.sql -d -7 /c "cmd /c del /f path"::设置时间变量set "Ymd%date:~0,4%%date:~5,2%%date:~…

田字描红贴

<html> <title>田字描红贴</title> <head> <style> canvas { border:1px solid gray; } </style> </head> <body> <div align"center"><canvas id"canvas"></canvas></div> <…

【Mysql】Mysql的字符集和比较规则(三)

字符集和比较规则简介 字符集简介 我们知道在计算机中只能以二进制的方式对数据进行存储&#xff0c;那么他们之间是怎样对应并进行转换的&#xff1f;我们需要了解两个概念&#xff1a; 字符范围&#xff1a;我们可以将哪些字符转换成二进制数据&#xff0c;也就是规定好字…

专业144,总分440+,上岸西北工业大学827西工大信号与系统考研经验分享

我的初试备考从4月末&#xff0c;持续到初试前&#xff0c;这中间没有中断。 总的时间分配上&#xff0c;是数学>专业课>英语>政治&#xff0c;虽然大家可支配时间和基础千差万别&#xff0c;但是这么分配是没错的。 数学 时间安排&#xff1a;3月-7月&#xff1a;…

【LeetCode高频SQL50题-基础版】打卡第9天:第46~50题

文章目录 【LeetCode高频SQL50题-基础版】打卡第9天&#xff1a;第46~50题⛅前言患某种疾病的患者&#x1f512;题目&#x1f511;题解 第二高的薪水&#x1f512;题目&#x1f511;题解 按日期分组销售产品&#x1f512;题目&#x1f511;题解 列出指定时间段内所有的下单产品…

apache shiro安全框架反序列化漏洞

用linux搭建一个环境 配置下源vi /etc/apt/sources.list 源如果是kali官方的有时候会下载不了&#xff0c;改成中科大的源 更新下源apt-get update 安装docker-compose 重启kali 启动docker容器 apt-get install docker apt-get install docker-compose reboot service do…

Sql Server 数据库中的所有已定义的唯一约束 (列名称 合并过了)

查询Sql Server Database中的唯一约束 with UniqueBasic as (SELECTtab.name AS TableName, -- 表名称idx.name AS UniqueName, -- 唯一约束的名称col.name AS UniqueFieldName -- 唯一约束的表字段FROMsys.indexes idxJOIN sys.index_columns idxColON (idx.object_id idxCo…